"Fossies" - the Fresh Open Source Software Archive

Member "cpuid-20201006/cpuid.c" (6 Oct 2020, 464421 Bytes) of package /linux/misc/cpuid-20201006.src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cpuid.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 20200427_vs_20201006.

    1 /*
    2 ** cpuid dumps CPUID information for each CPU.
    3 ** Copyright 2003,2004,2005,2006,2010,2011,2012,2013,2014,2015,2016,2017,2018,
    4 ** 2020 by Todd Allen.
    5 ** 
    6 ** This program is free software; you can redistribute it and/or
    7 ** modify it under the terms of the GNU General Public License
    8 ** as published by the Free Software Foundation; either version 2
    9 ** of the License, or (at your option) any later version.
   10 ** 
   11 ** This program is distributed in the hope that it will be useful,
   12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 ** GNU General Public License for more details.
   15 ** 
   16 ** You should have received a copy of the GNU General Public License
   17 ** along with this program; if not, write to the Free Software Foundation, Inc.,
   18 ** 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   19 */
   20 
   21 // MSR_CPUID_table* is a table that appears in Intel document 325462, "Intel 64
   22 // and IA-32 Architectures Software Developer's Manual Combined Volumes: 1, 2A,
   23 // 2B, 2C, 2D, 3A, 3B, 3C, 3D, and 4" (the name changes from version to version
   24 // as more volumes are added).  The table moves around from version to version,
   25 // but in version 071US, was in "Volume 4: Model-Specific Registers", Table 2-1:
   26 // "CPUID Signature Values of DisplayFamily_DisplayModel".
   27 
   28 // MRG* is a table that forms the bulk of Intel Microcode Revision Guidance (or
   29 // Microcode Update Guidance).  Its purpose is not to list CPUID values, but
   30 // it does so, and sometimes lists values that appear nowhere else.
   31 
   32 // LX* indicates features that I have seen no documentation for, but which are
   33 // used by the Linux kernel (which is good evidence that they're correct).
   34 // The "hook" to find these generally is an X86_FEATURE_* flag in:
   35 //    arch/x86/include/asm/cpufeatures.h
   36 // For (synth) and (uarch synth) decoding, it often indicates
   37 // family/model/stepping values which are documented nowhere else.  These
   38 // usually can be found in:
   39 //    arch/x86/include/asm/intel-family.h
   40 
   41 // Coreboot* indicates (synth) or (uarch synth) decoding for which I have seen
   42 // no documentation, but which is used by coreboot, BIOS replacement software.
   43 // The core information is in:
   44 //    src/soc/intel/common/block/include/intelblocks/mp_init.h
   45 //    src/soc/intel/*/include/soc/cpu.h
   46 // And strings, for the less obvious cases, are in:
   47 //    src/soc/intel/*/bootblock/report_platform.c
   48 
   49 // Xen* indicates features that I have seen no documentation for, but which are
   50 // used by the Xen hypervisor.  They are listed in:
   51 //    tools/libxl/libxl_cpuid.c
   52 
   53 // Qemu* indicates features that I have seen no documentation for, but which are
   54 // used by the Qemu hypervisor.  They are listed in:
   55 //    target/i386/cpu.c
   56 
   57 // SKC* indicates features that I have seen no (or incomplete) documentation
   58 // for, but which were sent to me in patch form by Smita Koralahalli
   59 // Channabasappa of AMD.
   60 
   61 #ifdef __linux__
   62 #define USE_CPUID_MODULE
   63 #define USE_KERNEL_SCHED_SETAFFINITY
   64 #endif
   65 
   66 #if __GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ >= 40300
   67 #define USE_CPUID_COUNT
   68 #endif
   69 
   70 #if defined(__GNUC__)
   71 #define UNUSED __attribute((unused))
   72 #else
   73 #define UNUSED
   74 #endif
   75 
   76 #define _GNU_SOURCE
   77 #include <stdio.h>
   78 #include <sys/types.h>
   79 #include <sys/stat.h>
   80 #include <sys/sysmacros.h>
   81 #include <fcntl.h>
   82 #include <errno.h>
   83 #include <unistd.h>
   84 #include <stdlib.h>
   85 #include <string.h>
   86 #include <regex.h>
   87 #include <getopt.h>
   88 
   89 #if defined(__sun)
   90 #include <sys/processor.h>
   91 #include <sys/procset.h>
   92 #include <strings.h>
   93 #include <pthread.h>
   94 #endif
   95 
   96 #ifdef USE_CPUID_MODULE
   97 #include <linux/major.h>
   98 #endif
   99 
  100 #ifdef USE_CPUID_COUNT
  101 #include <cpuid.h>
  102 #endif
  103 
  104 #ifdef USE_KERNEL_SCHED_SETAFFINITY
  105 #include <sys/syscall.h>
  106 #else
  107 #include <sched.h>
  108 #endif
  109 
  110 typedef int   boolean;
  111 #define TRUE  1
  112 #define FALSE 0
  113 
  114 typedef char*              string;
  115 typedef const char*        cstring;
  116 typedef const char* const  ccstring;
  117 #define SAME  0
  118 
  119 #define STR(x)   #x
  120 #define XSTR(x)  STR(x)
  121 
  122 #ifndef MAX
  123 #define MAX(l,r)       ((l) > (r) ? (l) : (r))
  124 #endif
  125 
  126 #define LENGTH(array)  (sizeof(array) / sizeof(array[0]))
  127 
  128 #define BPI  32
  129 #define POWER2(power) \
  130    (1 << (power))
  131 #define RIGHTMASK(width) \
  132    (((width) >= BPI) ? ~0 : POWER2(width)-1)
  133 #define BIT_EXTRACT_LE(value, start, after) \
  134    (((value) & RIGHTMASK(after)) >> start)
  135 
  136 #define WORD_EAX  0
  137 #define WORD_EBX  1
  138 #define WORD_ECX  2
  139 #define WORD_EDX  3
  140 
  141 #define WORD_NUM  4
  142 
  143 const char*  program = NULL;
  144 
  145 static boolean  strregexp(const char*  haystack,
  146                           const char*  needle)
  147 {
  148    regex_t  re;
  149    int      status;
  150    status = regcomp(&re, needle, REG_NOSUB);
  151    if (status != 0) {
  152       size_t  size = regerror(status, &re, NULL, 0);
  153       char*   buffer = malloc(size + 1);
  154       if (buffer == NULL || size + 1 == 0) {
  155          fprintf(stderr, "%s: out of memory\n", program);
  156          exit(1);
  157       }
  158       regerror(status, &re, buffer, size);
  159       fprintf(stderr, "%s: cannot regcomp \"%s\"; error = %s\n",
  160               program, needle, buffer);
  161       exit(1);
  162    }
  163    status = regexec(&re, haystack, 0, NULL, 0);
  164    if (status != 0 && status != REG_NOMATCH) {
  165       size_t  size = regerror(status, &re, NULL, 0);
  166       char*   buffer = malloc(size + 1);
  167       if (buffer == NULL || size + 1 == 0) {
  168          fprintf(stderr, "%s: out of memory\n", program);
  169          exit(1);
  170       }
  171       regerror(status, &re, buffer, size);
  172       fprintf(stderr, "%s: cannot regexec string \"%s\" with regexp \"%s\";"
  173               " error = %s\n",
  174               program, haystack, needle, buffer);
  175       exit(1);
  176    }
  177    regfree(&re);
  178 
  179    return (status == 0);
  180 }
  181 
  182 typedef struct {
  183    ccstring      name;
  184    unsigned int  low_bit;
  185    unsigned int  high_bit;
  186    ccstring*     images;
  187 } named_item;
  188 
  189 #define NIL_IMAGES     (ccstring*)NULL
  190 #define MINUS1_IMAGES  (ccstring*)1
  191 #define X2_IMAGES      (ccstring*)2
  192 
  193 static unsigned int
  194 get_max_len (named_item    names[],
  195              unsigned int  length)
  196 {
  197    unsigned int  result = 0;
  198    unsigned int  i;
  199 
  200    for (i = 0; i < length; i++) {
  201       result = MAX(result, strlen(names[i].name));
  202    }
  203 
  204    return result;
  205 }
  206 
  207 static void
  208 print_names(unsigned int  value,
  209             named_item    names[],
  210             unsigned int  length,
  211             unsigned int  max_len)
  212 {
  213    unsigned int  i;
  214 
  215    if (max_len == 0) {
  216       max_len = get_max_len(names, length);
  217    }
  218 
  219    for (i = 0; i < length; i++) {
  220       unsigned int  field = BIT_EXTRACT_LE(value,
  221                                            names[i].low_bit,
  222                                            names[i].high_bit + 1);
  223       if (names[i].images == X2_IMAGES) {
  224          printf("      %-*s = %.1f\n",
  225                 max_len,
  226                 names[i].name,
  227                 (double)field / 2.0);
  228       } else if (names[i].images == MINUS1_IMAGES) {
  229          printf("      %-*s = 0x%0llx (%llu)\n",
  230                 max_len,
  231                 names[i].name,
  232                 (unsigned long long)field + 1ULL,
  233                 (unsigned long long)field + 1ULL);
  234       } else if (names[i].images == NIL_IMAGES
  235                  || names[i].images[field] == NULL) {
  236          printf("      %-*s = 0x%0x (%u)\n",
  237                 max_len,
  238                 names[i].name,
  239                 field,
  240                 field);
  241       } else {
  242          printf("      %-*s = %s\n",
  243                 max_len,
  244                 names[i].name,
  245                 names[i].images[field]);
  246       }
  247    }
  248 }
  249 
  250 static ccstring  bools[] = { "false",
  251                              "true" };
  252 
  253 typedef enum {
  254    VENDOR_UNKNOWN,
  255    VENDOR_INTEL,
  256    VENDOR_AMD,
  257    VENDOR_CYRIX,
  258    VENDOR_VIA,
  259    VENDOR_TRANSMETA,
  260    VENDOR_UMC,
  261    VENDOR_NEXGEN,
  262    VENDOR_RISE,
  263    VENDOR_SIS,
  264    VENDOR_NSC,
  265    VENDOR_VORTEX,
  266    VENDOR_RDC,
  267    VENDOR_HYGON,
  268    VENDOR_ZHAOXIN,
  269 } vendor_t;
  270 
  271 typedef enum {
  272    HYPERVISOR_UNKNOWN,
  273    HYPERVISOR_VMWARE,
  274    HYPERVISOR_XEN,
  275    HYPERVISOR_KVM,
  276    HYPERVISOR_MICROSOFT,
  277 } hypervisor_t;
  278 
  279 #define __F(v)     ((v) & 0x0ff00f00)
  280 #define __M(v)     ((v) & 0x000f00f0)
  281 #define __FM(v)    ((v) & 0x0fff0ff0)
  282 #define __FMS(v)   ((v) & 0x0fff0fff)
  283 
  284 #define __TF(v)    ((v) & 0x0ff03f00)
  285 #define __TFM(v)   ((v) & 0x0fff3ff0)
  286 #define __TFMS(v)  ((v) & 0x0fff3fff)
  287 
  288 #define _T(v)      ((v) << 12)
  289 #define _F(v)      ((v) << 8)
  290 #define _M(v)      ((v) << 4)
  291 #define _S(v)      (v)
  292 #define _XF(v)     ((v) << 20)
  293 #define _XM(v)     ((v) << 16)
  294 
  295 #define __B(v)     ((v) & 0x000000ff)
  296 #define _B(v)      (v)
  297 
  298 #define _FM(xf,f,xm,m)     (_XF(xf) + _F(f) + _XM(xm) + _M(m))
  299 #define _FMS(xf,f,xm,m,s)  (_XF(xf) + _F(f) + _XM(xm) + _M(m) + _S(s))
  300 
  301 #define START \
  302    if (0)
  303 #define F(xf,f,...) \
  304    else if (__F(val)    ==       _XF(xf)        +_F(f)                              ) ACT(__VA_ARGS__)
  305 #define FM(xf,f,xm,m,...) \
  306    else if (__FM(val)   ==       _XF(xf)+_XM(xm)+_F(f)+_M(m)                        ) ACT(__VA_ARGS__)
  307 #define FMS(xf,f,xm,m,s,...) \
  308    else if (__FMS(val)  ==       _XF(xf)+_XM(xm)+_F(f)+_M(m)+_S(s)                  ) ACT(__VA_ARGS__)
  309 #define TF(t,xf,f,...) \
  310    else if (__TF(val)   == _T(t)+_XF(xf)        +_F(f)                              ) ACT(__VA_ARGS__)
  311 #define TFM(t,xf,f,xm,m,...) \
  312    else if (__TFM(val)  == _T(t)+_XF(xf)+_XM(xm)+_F(f)+_M(m)                        ) ACT(__VA_ARGS__)
  313 #define TFMS(t,xf,f,xm,m,s,...) \
  314    else if (__TFMS(val) == _T(t)+_XF(xf)+_XM(xm)+_F(f)+_M(m)+_S(s)                  ) ACT(__VA_ARGS__)
  315 #define FQ(xf,f,q,...) \
  316    else if (__F(val)    ==       _XF(xf)        +_F(f)             && (stash) && (q)) ACT(__VA_ARGS__)
  317 #define FMQ(xf,f,xm,m,q,...) \
  318    else if (__FM(val)   ==       _XF(xf)+_XM(xm)+_F(f)+_M(m)       && (stash) && (q)) ACT(__VA_ARGS__)
  319 #define FMSQ(xf,f,xm,m,s,q,...) \
  320    else if (__FMS(val)  ==       _XF(xf)+_XM(xm)+_F(f)+_M(m)+_S(s) && (stash) && (q)) ACT(__VA_ARGS__)
  321 #define DEFAULT(...) \
  322    else                                                                               ACT(__VA_ARGS__)
  323 #define FALLBACK(...) \
  324    else __VA_ARGS__
  325 
  326 typedef struct {
  327    vendor_t       vendor;
  328    boolean        saw_4;
  329    boolean        saw_b;
  330    boolean        saw_1f;
  331    unsigned int   val_0_eax;
  332    unsigned int   val_1_eax;
  333    unsigned int   val_1_ebx;
  334    unsigned int   val_1_ecx;
  335    unsigned int   val_1_edx;
  336    unsigned int   val_4_eax;
  337    unsigned int   val_b_eax[2];
  338    unsigned int   val_b_ebx[2];
  339    unsigned int   val_1f_eax[6];
  340    unsigned int   val_1f_ebx[6];
  341    unsigned int   val_1f_ecx[6];
  342    unsigned int   val_80000001_eax;
  343    unsigned int   val_80000001_ebx;
  344    unsigned int   val_80000001_ecx;
  345    unsigned int   val_80000001_edx;
  346    unsigned int   val_80000008_ecx;
  347    unsigned int   val_8000001e_ebx;
  348    unsigned int   transmeta_proc_rev;
  349    char           brand[48+1];
  350    char           transmeta_info[64+1];
  351    char           override_brand[48*2+1];
  352    char           soc_brand[48+1];
  353    hypervisor_t   hypervisor;
  354 
  355    struct mp {
  356       const char*    method;
  357       unsigned int   cores;
  358       unsigned int   hyperthreads;
  359    } mp;
  360 
  361    struct br {
  362       boolean    mobile;
  363 
  364       struct /* Intel */ {
  365          boolean    celeron;
  366          boolean    core;
  367          boolean    pentium;
  368          boolean    atom;
  369          boolean    xeon_mp;
  370          boolean    xeon;
  371          boolean    pentium_m;
  372          boolean    pentium_d;
  373          boolean    extreme;
  374          boolean    generic;
  375          boolean    scalable;
  376          boolean    u_line;
  377          boolean    y_line;
  378          boolean    g_line;
  379          boolean    i_8000;
  380          boolean    i_10000;
  381          boolean    cc150;
  382       };
  383       struct /* AMD */ {
  384          boolean    athlon_lv;
  385          boolean    athlon_xp;
  386          boolean    duron;
  387          boolean    athlon;
  388          boolean    sempron;
  389          boolean    phenom;
  390          boolean    series;
  391          boolean    a_series;
  392          boolean    c_series;
  393          boolean    e_series;
  394          boolean    g_series;
  395          boolean    r_series;
  396          boolean    z_series;
  397          boolean    geode;
  398          boolean    turion;
  399          boolean    neo;
  400          boolean    athlon_fx;
  401          boolean    athlon_mp;
  402          boolean    duron_mp;
  403          boolean    opteron;
  404          boolean    fx;
  405          boolean    firepro;
  406          boolean    ultra;
  407          boolean    t_suffix;
  408          boolean    ryzen;
  409          boolean    epyc;
  410          boolean    epyc_3000;
  411 
  412          boolean    embedded;
  413          int        cores;
  414       };
  415       struct /* Cyrix */ {
  416          boolean    mediagx;
  417       };
  418       struct /* VIA */ {
  419          boolean    c7;
  420          boolean    c7m;
  421          boolean    c7d;
  422          boolean    eden;
  423          boolean    zhaoxin;
  424       };
  425    } br;
  426    struct bri {
  427       boolean  desktop_pentium;
  428       boolean  desktop_celeron;
  429       boolean  mobile_pentium;
  430       boolean  mobile_pentium_m;
  431       boolean  mobile_celeron;
  432       boolean  xeon_mp;
  433       boolean  xeon;
  434    } bri;
  435 
  436                                 /* ==============implications============== */
  437                                 /* PII (F6, M5)            PIII (F6, M7)    */
  438                                 /* ----------------------  ---------------  */
  439    boolean       L2_4w_1Mor2M;  /* Xeon                    Xeon             */
  440    boolean       L2_4w_512K;    /* normal, Mobile or Xeon  normal or Xeon   */
  441    boolean       L2_4w_256K;    /* Mobile                   -               */
  442    boolean       L2_8w_1Mor2M;  /*  -                      Xeon             */
  443    boolean       L2_8w_512K;    /*  -                      normal           */
  444    boolean       L2_8w_256K;    /*  -                      normal or Xeon   */
  445                  /* none */     /* Celeron                  -               */
  446 
  447    boolean       L2_2M;         /* Nocona lacks, Irwindale has */
  448                                 /* Conroe has more, Allendale has this */
  449    boolean       L2_6M;         /* Yorkfield C1/E0 has this, M1/R0 has less */
  450    boolean       L3;            /* Cranford lacks, Potomac has */
  451 
  452    boolean       L2_256K;       /* Barton has more, Thorton has this */
  453    boolean       L2_512K;       /* Toledo has more, Manchester E6 has this */
  454 } code_stash_t;
  455 
  456 #define NIL_STASH { VENDOR_UNKNOWN, \
  457                     FALSE, FALSE, FALSE, \
  458                     0, 0, 0, 0, 0, 0, \
  459                     { 0, 0 }, \
  460                     { 0, 0 }, \
  461                     { 0, 0, 0, 0, 0, 0 }, \
  462                     { 0, 0, 0, 0, 0, 0 }, \
  463                     { 0, 0, 0, 0, 0, 0 }, \
  464                     0, 0, 0, 0, 0, 0, 0, \
  465                     "", "", "", "", \
  466                     HYPERVISOR_UNKNOWN, \
  467                     { NULL, -1, -1 }, \
  468                     { FALSE, \
  469                       { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, \
  470                         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, \
  471                         FALSE, FALSE, FALSE },                           \
  472                       { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, \
  473                         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, \
  474                         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, \
  475                         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, \
  476                         FALSE, 0 }, \
  477                       { FALSE }, \
  478                       { FALSE, FALSE, FALSE, FALSE, FALSE } }, \
  479                     { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, \
  480                     FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, \
  481                     FALSE, FALSE, FALSE, \
  482                     FALSE, FALSE }
  483 
  484 static void
  485 decode_amd_model(const code_stash_t*  stash,
  486                  const char**         brand_pre,
  487                  const char**         brand_post,
  488                  char*                proc)
  489 {
  490    *brand_pre  = NULL;
  491    *brand_post = NULL;
  492    *proc       = '\0';
  493 
  494    if (stash == NULL) return;
  495 
  496    if (__F(stash->val_1_eax) == _XF(0) + _F(15)
  497        && __M(stash->val_1_eax) < _XM(4) + _M(0)) {
  498       /*
  499       ** Algorithm from:
  500       **    Revision Guide for AMD Athlon 64 and AMD Opteron Processors 
  501       **    (25759 Rev 3.79), Constructing the Processor Name String.
  502       ** But using only the Processor numbers.
  503       */
  504       unsigned int  bti;
  505       unsigned int  NN;
  506 
  507       if (__B(stash->val_1_ebx) != 0) {
  508          bti = BIT_EXTRACT_LE(__B(stash->val_1_ebx), 5, 8) << 2;
  509          NN  = BIT_EXTRACT_LE(__B(stash->val_1_ebx), 0, 5);
  510       } else if (BIT_EXTRACT_LE(stash->val_80000001_ebx, 0, 12) != 0) {
  511          bti = BIT_EXTRACT_LE(stash->val_80000001_ebx, 6, 12);
  512          NN  = BIT_EXTRACT_LE(stash->val_80000001_ebx, 0,  6);
  513       } else {
  514          return;
  515       }
  516 
  517 #define XX  (22 + NN)
  518 #define YY  (38 + 2*NN)
  519 #define ZZ  (24 + NN)
  520 #define TT  (24 + NN)
  521 #define RR  (45 + 5*NN)
  522 #define EE  ( 9 + NN)
  523 
  524       switch (bti) {
  525       case 0x04:
  526          *brand_pre = "AMD Athlon(tm) 64";
  527          sprintf(proc, "Processor %02d00+", XX);
  528          break;
  529       case 0x05:
  530          *brand_pre = "AMD Athlon(tm) 64 X2 Dual Core";
  531          sprintf(proc, "Processor %02d00+", XX);
  532          break;
  533       case 0x06:
  534          *brand_pre  = "AMD Athlon(tm) 64";
  535          sprintf(proc, "FX-%02d", ZZ);
  536          *brand_post = "Dual Core";
  537          break;
  538       case 0x08:
  539          *brand_pre = "AMD Athlon(tm) 64";
  540          sprintf(proc, "Processor %02d00+", XX);
  541          break;
  542       case 0x09:
  543          *brand_pre = "AMD Athlon(tm) 64";
  544          sprintf(proc, "Processor %02d00+", XX);
  545          break;
  546       case 0x0a:
  547          *brand_pre = "AMD Turion(tm) Mobile Technology";
  548          sprintf(proc, "ML-%02d", XX);
  549          break;
  550       case 0x0b:
  551          *brand_pre = "AMD Turion(tm) Mobile Technology";
  552          sprintf(proc, "MT-%02d", XX);
  553          break;
  554       case 0x0c:
  555       case 0x0d:
  556          *brand_pre = "AMD Opteron(tm)";
  557          sprintf(proc, "Processor 1%02d", YY);
  558          break;
  559       case 0x0e:
  560          *brand_pre = "AMD Opteron(tm)";
  561          sprintf(proc, "Processor 1%02d HE", YY);
  562          break;
  563       case 0x0f:
  564          *brand_pre = "AMD Opteron(tm)";
  565          sprintf(proc, "Processor 1%02d EE", YY);
  566          break;
  567       case 0x10:
  568       case 0x11:
  569          *brand_pre = "AMD Opteron(tm)";
  570          sprintf(proc, "Processor 2%02d", YY);
  571          break;
  572       case 0x12:
  573          *brand_pre = "AMD Opteron(tm)";
  574          sprintf(proc, "Processor 2%02d HE", YY);
  575          break;
  576       case 0x13:
  577          *brand_pre = "AMD Opteron(tm)";
  578          sprintf(proc, "Processor 2%02d EE", YY);
  579          break;
  580       case 0x14:
  581       case 0x15:
  582          *brand_pre = "AMD Opteron(tm)";
  583          sprintf(proc, "Processor 8%02d", YY);
  584          break;
  585       case 0x16:
  586          *brand_pre = "AMD Opteron(tm)";
  587          sprintf(proc, "Processor 8%02d HE", YY);
  588          break;
  589       case 0x17:
  590          *brand_pre = "AMD Opteron(tm)";
  591          sprintf(proc, "Processor 8%02d EE", YY);
  592          break;
  593       case 0x18:
  594          *brand_pre = "AMD Athlon(tm) 64";
  595          sprintf(proc, "Processor %02d00+", EE);
  596          break;
  597       case 0x1d:
  598          *brand_pre = "Mobile AMD Athlon(tm) XP-M";
  599          sprintf(proc, "Processor %02d00+", XX);
  600          break;
  601       case 0x1e:
  602          *brand_pre = "Mobile AMD Athlon(tm) XP-M";
  603          sprintf(proc, "Processor %02d00+", XX);
  604          break;
  605       case 0x20:
  606          *brand_pre = "AMD Athlon(tm) XP";
  607          sprintf(proc, "Processor %02d00+", XX);
  608          break;
  609       case 0x21:
  610       case 0x23:
  611          *brand_pre = "Mobile AMD Sempron(tm)";
  612          sprintf(proc, "Processor %02d00+", TT);
  613          break;
  614       case 0x22:
  615       case 0x26:
  616          *brand_pre = "AMD Sempron(tm)";
  617          sprintf(proc, "Processor %02d00+", TT);
  618          break;
  619       case 0x24:
  620          *brand_pre = "AMD Athlon(tm) 64";
  621          sprintf(proc, "FX-%02d", ZZ);
  622          break;
  623       case 0x29:
  624       case 0x2c:
  625       case 0x2d:
  626       case 0x38:
  627       case 0x3b:
  628          *brand_pre = "Dual Core AMD Opteron(tm)";
  629          sprintf(proc, "Processor 1%02d", RR);
  630          break;
  631       case 0x2a:
  632       case 0x30:
  633       case 0x31:
  634       case 0x39:
  635       case 0x3c:
  636          *brand_pre = "Dual Core AMD Opteron(tm)";
  637          sprintf(proc, "Processor 2%02d", RR);
  638          break;
  639       case 0x2b:
  640       case 0x34:
  641       case 0x35:
  642       case 0x3a:
  643       case 0x3d:
  644          *brand_pre = "Dual Core AMD Opteron(tm)";
  645          sprintf(proc, "Processor 8%02d", RR);
  646          break;
  647       case 0x2e:
  648          *brand_pre = "Dual Core AMD Opteron(tm)";
  649          sprintf(proc, "Processor 1%02d HE", RR);
  650          break;
  651       case 0x2f:
  652          *brand_pre = "Dual Core AMD Opteron(tm)";
  653          sprintf(proc, "Processor 1%02d EE", RR);
  654          break;
  655       case 0x32:
  656          *brand_pre = "Dual Core AMD Opteron(tm)";
  657          sprintf(proc, "Processor 2%02d HE", RR);
  658          break;
  659       case 0x33:
  660          *brand_pre = "Dual Core AMD Opteron(tm)";
  661          sprintf(proc, "Processor 2%02d EE", RR);
  662          break;
  663       case 0x36:
  664          *brand_pre = "Dual Core AMD Opteron(tm)";
  665          sprintf(proc, "Processor 8%02d HE", RR);
  666          break;
  667       case 0x37:
  668          *brand_pre = "Dual Core AMD Opteron(tm)";
  669          sprintf(proc, "Processor 8%02d EE", RR);
  670          break;
  671       }
  672 
  673 #undef XX
  674 #undef YY
  675 #undef ZZ
  676 #undef TT
  677 #undef RR
  678 #undef EE
  679    } else if (__F(stash->val_1_eax) == _XF(0) + _F(15)
  680               && __M(stash->val_1_eax) >= _XM(4) + _M(0)) {
  681       /*
  682       ** Algorithm from:
  683       **    Revision Guide for AMD NPT Family 0Fh Processors (33610 Rev 3.46),
  684       **    Constructing the Processor Name String.
  685       ** But using only the Processor numbers.
  686       */
  687       unsigned int  bti;
  688       unsigned int  pwrlmt;
  689       unsigned int  NN;
  690       unsigned int  pkgtype;
  691       unsigned int  cmpcap;
  692 
  693       pwrlmt  = ((BIT_EXTRACT_LE(stash->val_80000001_ebx, 6, 9) << 1)
  694                  + BIT_EXTRACT_LE(stash->val_80000001_ebx, 14, 15));
  695       bti     = BIT_EXTRACT_LE(stash->val_80000001_ebx, 9, 14);
  696       NN      = ((BIT_EXTRACT_LE(stash->val_80000001_ebx, 15, 16) << 5)
  697                  + BIT_EXTRACT_LE(stash->val_80000001_ebx, 0, 5));
  698       pkgtype = BIT_EXTRACT_LE(stash->val_80000001_eax, 4, 6);
  699       cmpcap  = ((BIT_EXTRACT_LE(stash->val_80000008_ecx, 0, 8) > 0)
  700                  ? 0x1 : 0x0);
  701 
  702 #define RR  (NN - 1)
  703 #define PP  (26 + NN)
  704 #define TT  (15 + cmpcap*10 + NN)
  705 #define ZZ  (57 + NN)
  706 #define YY  (29 + NN)
  707 
  708 #define PKGTYPE(pkgtype)  ((pkgtype) << 11)
  709 #define CMPCAP(cmpcap)    ((cmpcap)  <<  9)
  710 #define BTI(bti)          ((bti)     <<  4)
  711 #define PWRLMT(pwrlmt)    (pwrlmt)
  712 
  713       switch (PKGTYPE(pkgtype) + CMPCAP(cmpcap) + BTI(bti) + PWRLMT(pwrlmt)) {
  714       /* Table 7: Name String Table for F (1207) and Fr3 (1207) Processors */
  715       case PKGTYPE(1) + CMPCAP(0) + BTI(1) + PWRLMT(2):
  716          *brand_pre = "AMD Opteron(tm)";
  717          sprintf(proc, "Processor 22%02d EE", RR);
  718          break;
  719       case PKGTYPE(1) + CMPCAP(1) + BTI(1) + PWRLMT(2):
  720          *brand_pre = "Dual-Core AMD Opteron(tm)";
  721          sprintf(proc, "Processor 22%02d EE", RR);
  722          break;
  723       case PKGTYPE(1) + CMPCAP(1) + BTI(0) + PWRLMT(2) :
  724          *brand_pre = "Dual-Core AMD Opteron(tm)";
  725          sprintf(proc, "Processor 12%02d EE", RR);
  726          break;
  727       case PKGTYPE(1) + CMPCAP(1) + BTI(0) + PWRLMT(6):
  728          *brand_pre = "Dual-Core AMD Opteron(tm)";
  729          sprintf(proc, "Processor 12%02d HE", RR);
  730          break;
  731       case PKGTYPE(1) + CMPCAP(1) + BTI(1) + PWRLMT(6):
  732          *brand_pre = "Dual-Core AMD Opteron(tm)";
  733          sprintf(proc, "Processor 22%02d HE", RR);
  734          break;
  735       case PKGTYPE(1) + CMPCAP(1) + BTI(1) + PWRLMT(10):
  736          *brand_pre = "Dual-Core AMD Opteron(tm)";
  737          sprintf(proc, "Processor 22%02d", RR);
  738          break;
  739       case PKGTYPE(1) + CMPCAP(1) + BTI(1) + PWRLMT(12):
  740          *brand_pre = "Dual-Core AMD Opteron(tm)";
  741          sprintf(proc, "Processor 22%02d SE", RR);
  742          break;
  743       case PKGTYPE(1) + CMPCAP(1) + BTI(4) + PWRLMT(2):
  744          *brand_pre = "Dual-Core AMD Opteron(tm)";
  745          sprintf(proc, "Processor 82%02d EE", RR);
  746          break;
  747       case PKGTYPE(1) + CMPCAP(1) + BTI(4) + PWRLMT(6):
  748          *brand_pre = "Dual-Core AMD Opteron(tm)";
  749          sprintf(proc, "Processor 82%02d HE", RR);
  750          break;
  751       case PKGTYPE(1) + CMPCAP(1) + BTI(4) + PWRLMT(10):
  752          *brand_pre = "Dual-Core AMD Opteron(tm)";
  753          sprintf(proc, "Processor 82%02d", RR);
  754          break;
  755       case PKGTYPE(1) + CMPCAP(1) + BTI(4) + PWRLMT(12):
  756          *brand_pre = "Dual-Core AMD Opteron(tm)";
  757          sprintf(proc, "Processor 82%02d SE", RR);
  758          break;
  759       case PKGTYPE(1) + CMPCAP(1) + BTI(6) + PWRLMT(14):
  760          *brand_pre = "AMD Athlon(tm) 64";
  761          sprintf(proc, "FX-%02d", ZZ);
  762          break;
  763       /* Table 8: Name String Table for AM2 and ASB1 Processors */
  764       case PKGTYPE(3) + CMPCAP(0) + BTI(1) + PWRLMT(5):
  765          *brand_pre = "AMD Sempron(tm)";
  766          sprintf(proc, "Processor LE-1%02d0", RR);
  767          break;
  768       case PKGTYPE(3) + CMPCAP(0) + BTI(2) + PWRLMT(6):
  769          *brand_pre = "AMD Athlon(tm)";
  770          sprintf(proc, "Processor LE-1%02d0", ZZ);
  771          break;
  772       case PKGTYPE(3) + CMPCAP(0) + BTI(3) + PWRLMT(6):
  773          *brand_pre = "AMD Athlon(tm)";
  774          sprintf(proc, "Processor 1%02d0B", ZZ);
  775          break;
  776       case PKGTYPE(3) + CMPCAP(0) + BTI(4) + PWRLMT(1):
  777       case PKGTYPE(3) + CMPCAP(0) + BTI(4) + PWRLMT(2):
  778       case PKGTYPE(3) + CMPCAP(0) + BTI(4) + PWRLMT(3):
  779       case PKGTYPE(3) + CMPCAP(0) + BTI(4) + PWRLMT(4):
  780       case PKGTYPE(3) + CMPCAP(0) + BTI(4) + PWRLMT(5):
  781       case PKGTYPE(3) + CMPCAP(0) + BTI(4) + PWRLMT(8):
  782          *brand_pre = "AMD Athlon(tm) 64";
  783          sprintf(proc, "Processor %02d00+", TT);
  784          break;
  785       case PKGTYPE(3) + CMPCAP(0) + BTI(5) + PWRLMT(2):
  786          *brand_pre = "AMD Sempron(tm)";
  787          sprintf(proc, "Processor %02d50p", RR);
  788          break;
  789       case PKGTYPE(3) + CMPCAP(0) + BTI(6) + PWRLMT(4):
  790       case PKGTYPE(3) + CMPCAP(0) + BTI(6) + PWRLMT(8):
  791          *brand_pre = "AMD Sempron(tm)";
  792          sprintf(proc, "Processor %02d00+", TT);
  793          break;
  794       case PKGTYPE(3) + CMPCAP(0) + BTI(7) + PWRLMT(1):
  795       case PKGTYPE(3) + CMPCAP(0) + BTI(7) + PWRLMT(2):
  796          *brand_pre = "AMD Sempron(tm)";
  797          sprintf(proc, "Processor %02d0U", TT);
  798          break;
  799       case PKGTYPE(3) + CMPCAP(0) + BTI(8) + PWRLMT(2):
  800       case PKGTYPE(3) + CMPCAP(0) + BTI(8) + PWRLMT(3):
  801          *brand_pre = "AMD Athlon(tm)";
  802          sprintf(proc, "Processor %02d50e", TT);
  803          break;
  804       case PKGTYPE(3) + CMPCAP(0) + BTI(9) + PWRLMT(2):
  805          *brand_pre = "AMD Athlon(tm) Neo";
  806          sprintf(proc, "Processor MV-%02d", TT);
  807          break;
  808       case PKGTYPE(3) + CMPCAP(0) + BTI(12) + PWRLMT(2):
  809          *brand_pre = "AMD Sempron(tm)";
  810          sprintf(proc, "Processor 2%02dU", RR);
  811          break;
  812       case PKGTYPE(3) + CMPCAP(1) + BTI(1) + PWRLMT(6):
  813          *brand_pre = "Dual-Core AMD Opteron(tm)";
  814          sprintf(proc, "Processor 12%02d HE", RR);
  815          break;
  816       case PKGTYPE(3) + CMPCAP(1) + BTI(1) + PWRLMT(10):
  817          *brand_pre = "Dual-Core AMD Opteron(tm)";
  818          sprintf(proc, "Processor 12%02d", RR);
  819          break;
  820       case PKGTYPE(3) + CMPCAP(1) + BTI(1) + PWRLMT(12):
  821          *brand_pre = "Dual-Core AMD Opteron(tm)";
  822          sprintf(proc, "Processor 12%02d SE", RR);
  823          break;
  824       case PKGTYPE(3) + CMPCAP(1) + BTI(3) + PWRLMT(3):
  825          *brand_pre = "AMD Athlon(tm) X2 Dual Core";
  826          sprintf(proc, "Processor BE-2%02d0", TT);
  827          break;
  828       case PKGTYPE(3) + CMPCAP(1) + BTI(4) + PWRLMT(1):
  829       case PKGTYPE(3) + CMPCAP(1) + BTI(4) + PWRLMT(2):
  830       case PKGTYPE(3) + CMPCAP(1) + BTI(4) + PWRLMT(6):
  831       case PKGTYPE(3) + CMPCAP(1) + BTI(4) + PWRLMT(8):
  832       case PKGTYPE(3) + CMPCAP(1) + BTI(4) + PWRLMT(12):
  833          *brand_pre = "AMD Athlon(tm) 64 X2 Dual Core";
  834          sprintf(proc, "Processor %02d00+", TT);
  835          break;
  836       case PKGTYPE(3) + CMPCAP(1) + BTI(5) + PWRLMT(12):
  837          *brand_pre  = "AMD Athlon(tm) 64";
  838          sprintf(proc, "FX-%02d", ZZ);
  839          *brand_post = "Dual Core";
  840          break;
  841       case PKGTYPE(3) + CMPCAP(1) + BTI(6) + PWRLMT(6):
  842          *brand_pre = "AMD Sempron(tm) Dual Core";
  843          sprintf(proc, "Processor %02d00", RR);
  844          break;
  845       case PKGTYPE(3) + CMPCAP(1) + BTI(7) + PWRLMT(3):
  846          *brand_pre = "AMD Athlon(tm) Dual Core";
  847          sprintf(proc, "Processor %02d50e", TT);
  848          break;
  849       case PKGTYPE(3) + CMPCAP(1) + BTI(7) + PWRLMT(6):
  850       case PKGTYPE(3) + CMPCAP(1) + BTI(7) + PWRLMT(7):
  851          *brand_pre = "AMD Athlon(tm) Dual Core";
  852          sprintf(proc, "Processor %02d00B", TT);
  853          break;
  854       case PKGTYPE(3) + CMPCAP(1) + BTI(8) + PWRLMT(3):
  855          *brand_pre = "AMD Athlon(tm) Dual Core";
  856          sprintf(proc, "Processor %02d50B", TT);
  857          break;
  858       case PKGTYPE(3) + CMPCAP(1) + BTI(9) + PWRLMT(1):
  859          *brand_pre = "AMD Athlon(tm) X2 Dual Core";
  860          sprintf(proc, "Processor %02d50e", TT);
  861          break;
  862       case PKGTYPE(3) + CMPCAP(1) + BTI(10) + PWRLMT(1):
  863       case PKGTYPE(3) + CMPCAP(1) + BTI(10) + PWRLMT(2):
  864          *brand_pre = "AMD Athlon(tm) Neo X2 Dual Core";
  865          sprintf(proc, "Processor %02d50e", TT);
  866          break;
  867       case PKGTYPE(3) + CMPCAP(1) + BTI(11) + PWRLMT(0):
  868          *brand_pre = "AMD Turion(tm) Neo X2 Dual Core";
  869          sprintf(proc, "Processor L6%02d", RR);
  870          break;
  871       case PKGTYPE(3) + CMPCAP(1) + BTI(12) + PWRLMT(0):
  872          *brand_pre = "AMD Turion(tm) Neo X2 Dual Core";
  873          sprintf(proc, "Processor L3%02d", RR);
  874          break;
  875       /* Table 9: Name String Table for S1g1 Processors */
  876       case PKGTYPE(0) + CMPCAP(0) + BTI(1) + PWRLMT(2):
  877          *brand_pre = "AMD Athlon(tm) 64";
  878          sprintf(proc, "Processor %02d00+", TT);
  879          break;
  880       case PKGTYPE(0) + CMPCAP(0) + BTI(2) + PWRLMT(12):
  881          *brand_pre = "AMD Turion(tm) 64 Mobile Technology";
  882          sprintf(proc, "MK-%02d", YY);
  883          break;
  884       case PKGTYPE(0) + CMPCAP(0) + BTI(3) + PWRLMT(1):
  885          *brand_pre = "Mobile AMD Sempron(tm)";
  886          sprintf(proc, "Processor %02d00+", TT);
  887          break;
  888       case PKGTYPE(0) + CMPCAP(0) + BTI(3) + PWRLMT(6):
  889       case PKGTYPE(0) + CMPCAP(0) + BTI(3) + PWRLMT(12):
  890          *brand_pre = "Mobile AMD Sempron(tm)";
  891          sprintf(proc, "Processor %02d00+", PP);
  892          break;
  893       case PKGTYPE(0) + CMPCAP(0) + BTI(4) + PWRLMT(2):
  894          *brand_pre = "AMD Sempron(tm)";
  895          sprintf(proc, "Processor %02d00+", TT);
  896          break;
  897       case PKGTYPE(0) + CMPCAP(0) + BTI(6) + PWRLMT(4):
  898       case PKGTYPE(0) + CMPCAP(0) + BTI(6) + PWRLMT(6):
  899       case PKGTYPE(0) + CMPCAP(0) + BTI(6) + PWRLMT(12):
  900          *brand_pre = "AMD Athlon(tm)";
  901          sprintf(proc, "Processor TF-%02d", TT);
  902          break;
  903       case PKGTYPE(0) + CMPCAP(0) + BTI(7) + PWRLMT(3):
  904          *brand_pre = "AMD Athlon(tm)";
  905          sprintf(proc, "Processor L1%02d", RR);
  906          break;
  907       case PKGTYPE(0) + CMPCAP(1) + BTI(1) + PWRLMT(12):
  908          *brand_pre = "AMD Sempron(tm)";
  909          sprintf(proc, "Processor TJ-%02d", YY);
  910          break;
  911       case PKGTYPE(0) + CMPCAP(1) + BTI(2) + PWRLMT(12):
  912          *brand_pre = "AMD Turion(tm) 64 X2 Mobile Technology";
  913          sprintf(proc, "Processor TL-%02d", YY);
  914          break;
  915       case PKGTYPE(0) + CMPCAP(1) + BTI(3) + PWRLMT(4):
  916       case PKGTYPE(0) + CMPCAP(1) + BTI(3) + PWRLMT(12):
  917          *brand_pre = "AMD Turion(tm) 64 X2 Dual-Core";
  918          sprintf(proc, "Processor TK-%02d", YY);
  919          break;
  920       case PKGTYPE(0) + CMPCAP(1) + BTI(5) + PWRLMT(4):
  921          *brand_pre = "AMD Turion(tm) 64 X2 Dual Core";
  922          sprintf(proc, "Processor %02d00+", TT);
  923          break;
  924       case PKGTYPE(0) + CMPCAP(1) + BTI(6) + PWRLMT(2):
  925          *brand_pre = "AMD Turion(tm) X2 Dual Core";
  926          sprintf(proc, "Processor L3%02d", RR);
  927          break;
  928       case PKGTYPE(0) + CMPCAP(1) + BTI(7) + PWRLMT(4):
  929          *brand_pre = "AMD Turion(tm) X2 Dual Core";
  930          sprintf(proc, "Processor L5%02d", RR);
  931          break;
  932       }
  933       
  934 #undef RR
  935 #undef PP
  936 #undef TT
  937 #undef ZZ
  938 #undef YY
  939    } else if (__F(stash->val_1_eax) == _XF(1) + _F(15)
  940               || __F(stash->val_1_eax) == _XF(2) + _F(15)
  941               || __F(stash->val_1_eax) == _XF(3) + _F(15)
  942               || __F(stash->val_1_eax) == _XF(5) + _F(15)) {
  943       /*
  944       ** Algorithm from:
  945       **    AMD Revision Guide for AMD Family 10h Processors (41322 Rev 3.74)
  946       **    AMD Revision Guide for AMD Family 11h Processors (41788 Rev 3.08)
  947       **    AMD Revision Guide for AMD Family 12h Processors (44739 Rev 3.10)
  948       **    AMD Revision Guide for AMD Family 14h Models 00h-0Fh Processors
  949       **    (47534 Rev 3.00)
  950       ** But using only the Processor numbers.
  951       */
  952       unsigned int  str1;
  953       unsigned int  str2;
  954       unsigned int  pg;
  955       unsigned int  partialmodel;
  956       unsigned int  pkgtype;
  957       unsigned int  nc;
  958       const char*   s1;
  959       const char*   s2;
  960 
  961       str2         = BIT_EXTRACT_LE(stash->val_80000001_ebx,  0,  4);
  962       partialmodel = BIT_EXTRACT_LE(stash->val_80000001_ebx,  4, 11);
  963       str1         = BIT_EXTRACT_LE(stash->val_80000001_ebx, 11, 15);
  964       pg           = BIT_EXTRACT_LE(stash->val_80000001_ebx, 15, 16);
  965       pkgtype      = BIT_EXTRACT_LE(stash->val_80000001_ebx, 28, 32);
  966       nc           = BIT_EXTRACT_LE(stash->val_80000008_ecx,  0,  8);
  967 
  968 #define NC(nc)            ((nc)   << 9)
  969 #define PG(pg)            ((pg)   << 8)
  970 #define STR1(str1)        ((str1) << 4)
  971 #define STR2(str2)        (str2)
  972 
  973       /* 
  974       ** In every String2 Values table, there were special cases for
  975       ** pg == 0 && str2 == 15 which defined them as the empty string.
  976       ** But that produces the same result as an undefined string, so
  977       ** don't bother trying to handle them.
  978       */
  979       if (__F(stash->val_1_eax) == _XF(1) + _F(15)) {
  980          if (pkgtype >= 2) {
  981             partialmodel--;
  982          }
  983 
  984          /* Family 10h tables */
  985          switch (pkgtype) {
  986          case 0:
  987             /* 41322 3.74: table 14: String1 Values for Fr2, Fr5, and Fr6 (1207) Processors */
  988             switch (PG(pg) + NC(nc) + STR1(str1)) {
  989             case PG(0) + NC(3) + STR1(0): *brand_pre = "Quad-Core AMD Opteron(tm)"; s1 = "Processor 83"; break;
  990             case PG(0) + NC(3) + STR1(1): *brand_pre = "Quad-Core AMD Opteron(tm)"; s1 = "Processor 23"; break;
  991             case PG(0) + NC(5) + STR1(0): *brand_pre = "Six-Core AMD Opteron(tm)";  s1 = "Processor 84"; break;
  992             case PG(0) + NC(5) + STR1(1): *brand_pre = "Six-Core AMD Opteron(tm)";  s1 = "Processor 24"; break;
  993             case PG(1) + NC(3) + STR1(1): *brand_pre = "Embedded AMD Opteron(tm)";  s1 = "Processor ";   break;
  994             case PG(1) + NC(5) + STR1(1): *brand_pre = "Embedded AMD Opteron(tm)";  s1 = "Processor ";   break;
  995             default:                                                                s1 = NULL;           break;
  996             }
  997             /* 41322 3.74: table 15: String2 Values for Fr2, Fr5, and Fr6 (1207) Processors */
  998             switch (PG(pg) + NC(nc) + STR2(str2)) {
  999             case PG(0) + NC(3) + STR2(10): s2 = " SE";   break;
 1000             case PG(0) + NC(3) + STR2(11): s2 = " HE";   break;
 1001             case PG(0) + NC(3) + STR2(12): s2 = " EE";   break;
 1002             case PG(0) + NC(5) + STR2(0):  s2 = " SE";   break;
 1003             case PG(0) + NC(5) + STR2(1):  s2 = " HE";   break;
 1004             case PG(0) + NC(5) + STR2(2):  s2 = " EE";   break;
 1005             case PG(1) + NC(3) + STR2(1):  s2 = "GF HE"; break;
 1006             case PG(1) + NC(3) + STR2(2):  s2 = "HF HE"; break;
 1007             case PG(1) + NC(3) + STR2(3):  s2 = "VS";    break;
 1008             case PG(1) + NC(3) + STR2(4):  s2 = "QS HE"; break;
 1009             case PG(1) + NC(3) + STR2(5):  s2 = "NP HE"; break;
 1010             case PG(1) + NC(3) + STR2(6):  s2 = "KH HE"; break;
 1011             case PG(1) + NC(3) + STR2(7):  s2 = "KS HE"; break;
 1012             case PG(1) + NC(5) + STR2(1):  s2 = "QS";    break;
 1013             case PG(1) + NC(5) + STR2(2):  s2 = "KS HE"; break;
 1014             default:                       s2 = NULL;    break;
 1015             }
 1016             break;
 1017          case 1:
 1018             /* 41322 3.74: table 16: String1 Values for AM2r2 and AM3 Processors */
 1019             switch (PG(pg) + NC(nc) + STR1(str1)) {
 1020             case PG(0) + NC(0) + STR1(2):  *brand_pre = "AMD Sempron(tm)";           s1 = "1";            break;
 1021             /* This case obviously collides with one later */
 1022             /* case PG(0) + NC(0) + STR1(3): *brand_pre = "AMD Athlon(tm) II";         s1 = "AMD Athlon(tm) II 1"; */
 1023             case PG(0) + NC(0) + STR1(1):  *brand_pre = "AMD Athlon(tm)";            s1 = "";             break;
 1024             case PG(0) + NC(0) + STR1(3):  *brand_pre = "AMD Athlon(tm) II X2";      s1 = "2";            break;
 1025             case PG(0) + NC(0) + STR1(4):  *brand_pre = "AMD Athlon(tm) II X2";      s1 = "B";            break;
 1026             case PG(0) + NC(0) + STR1(5):  *brand_pre = "AMD Athlon(tm) II X2";      s1 = "";             break;
 1027             case PG(0) + NC(0) + STR1(7):  *brand_pre = "AMD Phenom(tm) II X2";      s1 = "5";            break;
 1028             case PG(0) + NC(0) + STR1(10): *brand_pre = "AMD Phenom(tm) II X2";      s1 = "";             break;
 1029             case PG(0) + NC(0) + STR1(11): *brand_pre = "AMD Phenom(tm) II X2";      s1 = "B";            break;
 1030             case PG(0) + NC(0) + STR1(12): *brand_pre = "AMD Sempron(tm) X2";        s1 = "1";            break;
 1031             case PG(0) + NC(2) + STR1(0):  *brand_pre = "AMD Phenom(tm)";            s1 = "";             break;
 1032             case PG(0) + NC(2) + STR1(3):  *brand_pre = "AMD Phenom(tm) II X3";      s1 = "B";            break;
 1033             case PG(0) + NC(2) + STR1(4):  *brand_pre = "AMD Phenom(tm) II X3";      s1 = "";             break;
 1034             case PG(0) + NC(2) + STR1(7):  *brand_pre = "AMD Phenom(tm) II X3";      s1 = "4";            break;
 1035             case PG(0) + NC(2) + STR1(8):  *brand_pre = "AMD Phenom(tm) II X3";      s1 = "7";            break;
 1036             case PG(0) + NC(2) + STR1(10): *brand_pre = "AMD Phenom(tm) II X3";      s1 = "";             break;
 1037             case PG(0) + NC(3) + STR1(0):  *brand_pre = "Quad-Core AMD Opteron(tm)"; s1 = "Processor 13"; break;
 1038             case PG(0) + NC(3) + STR1(2):  *brand_pre = "AMD Phenom(tm)";            s1 = "";             break;
 1039             case PG(0) + NC(3) + STR1(3):  *brand_pre = "AMD Phenom(tm) II X4";      s1 = "9";            break;
 1040             case PG(0) + NC(3) + STR1(4):  *brand_pre = "AMD Phenom(tm) II X4";      s1 = "8";            break;
 1041             case PG(0) + NC(3) + STR1(7):  *brand_pre = "AMD Phenom(tm) II X4";      s1 = "B";            break;
 1042             case PG(0) + NC(3) + STR1(8):  *brand_pre = "AMD Phenom(tm) II X4";      s1 = "";             break;
 1043             case PG(0) + NC(3) + STR1(10): *brand_pre = "AMD Athlon(tm) II X4";      s1 = "6";            break;
 1044             case PG(0) + NC(3) + STR1(15): *brand_pre = "AMD Athlon(tm) II X4";      s1 = "";             break;
 1045             case PG(0) + NC(5) + STR1(0):  *brand_pre = "AMD Phenom(tm) II X6";      s1 = "1";            break;
 1046             case PG(1) + NC(1) + STR1(1):  *brand_pre = "AMD Athlon(tm) II XLT V";   s1 = "";             break;
 1047             case PG(1) + NC(1) + STR1(2):  *brand_pre = "AMD Athlon(tm) II XL V";    s1 = "";             break;
 1048             case PG(1) + NC(3) + STR1(1):  *brand_pre = "AMD Phenom(tm) II XLT Q";   s1 = "";             break;
 1049             case PG(1) + NC(3) + STR1(2):  *brand_pre = "AMD Phenom(tm) II X4";      s1 = "9";            break;
 1050             case PG(1) + NC(3) + STR1(3):  *brand_pre = "AMD Phenom(tm) II X4";      s1 = "8";            break;
 1051             case PG(1) + NC(3) + STR1(4):  *brand_pre = "AMD Phenom(tm) II X4";      s1 = "6";            break;
 1052             default:                                                                 s1 = NULL;           break;
 1053             }
 1054             /* 41322 3.74: table 17: String2 Values for AM2r2 and AM3 Processors */
 1055             switch (PG(pg) + NC(nc) + STR2(str2)) {
 1056             case PG(0) + NC(0) + STR2(10): s2 = " Processor";                break;
 1057             case PG(0) + NC(0) + STR2(11): s2 = "u Processor";               break;
 1058             case PG(0) + NC(1) + STR2(3):  s2 = "50 Dual-Core Processor";    break;
 1059             case PG(0) + NC(1) + STR2(6):  s2 = " Processor";                break;
 1060             case PG(0) + NC(1) + STR2(7):  s2 = "e Processor";               break;
 1061             case PG(0) + NC(1) + STR2(9):  s2 = "0 Processor";               break;
 1062             case PG(0) + NC(1) + STR2(10): s2 = "0e Processor";              break;
 1063             case PG(0) + NC(1) + STR2(11): s2 = "u Processor";               break;
 1064             case PG(0) + NC(2) + STR2(0):  s2 = "00 Triple-Core Processor";  break;
 1065             case PG(0) + NC(2) + STR2(1):  s2 = "00e Triple-Core Processor"; break;
 1066             case PG(0) + NC(2) + STR2(2):  s2 = "00B Triple-Core Processor"; break;
 1067             case PG(0) + NC(2) + STR2(3):  s2 = "50 Triple-Core Processor";  break;
 1068             case PG(0) + NC(2) + STR2(4):  s2 = "50e Triple-Core Processor"; break;
 1069             case PG(0) + NC(2) + STR2(5):  s2 = "50B Triple-Core Processor"; break;
 1070             case PG(0) + NC(2) + STR2(6):  s2 = " Processor";                break;
 1071             case PG(0) + NC(2) + STR2(7):  s2 = "e Processor";               break;
 1072             case PG(0) + NC(2) + STR2(9):  s2 = "0e Processor";              break;
 1073             case PG(0) + NC(2) + STR2(10): s2 = "0 Processor";               break;
 1074             case PG(0) + NC(3) + STR2(0):  s2 = "00 Quad-Core Processor";    break;
 1075             case PG(0) + NC(3) + STR2(1):  s2 = "00e Quad-Core Processor";   break;
 1076             case PG(0) + NC(3) + STR2(2):  s2 = "00B Quad-Core Processor";   break;
 1077             case PG(0) + NC(3) + STR2(3):  s2 = "50 Quad-Core Processor";    break;
 1078             case PG(0) + NC(3) + STR2(4):  s2 = "50e Quad-Core Processor";   break;
 1079             case PG(0) + NC(3) + STR2(5):  s2 = "50B Quad-Core Processor";   break;
 1080             case PG(0) + NC(3) + STR2(6):  s2 = " Processor";                break;
 1081             case PG(0) + NC(3) + STR2(7):  s2 = "e Processor";               break;
 1082             case PG(0) + NC(3) + STR2(9):  s2 = "0e Processor";              break;
 1083             case PG(0) + NC(3) + STR2(14): s2 = "0 Processor";               break;
 1084             case PG(0) + NC(5) + STR2(0):  s2 = "5T Processor";              break;
 1085             case PG(0) + NC(5) + STR2(1):  s2 = "0T Processor";              break;
 1086             case PG(1) + NC(1) + STR2(1):  s2 = "L Processor";               break;
 1087             case PG(1) + NC(1) + STR2(2):  s2 = "C Processor";               break;
 1088             case PG(1) + NC(3) + STR2(1):  s2 = "L Processor";               break;
 1089             case PG(1) + NC(3) + STR2(4):  s2 = "T Processor";               break;
 1090             default:                       s2 = NULL;                        break;
 1091             }
 1092             break;
 1093          case 2:
 1094             /* 41322 3.74: table 18: String1 Values for S1g3 and S1g4 Processors */
 1095             switch (PG(pg) + NC(nc) + STR1(str1)) {
 1096             case PG(0) + NC(0) + STR1(0): *brand_pre = "AMD Sempron(tm)";                          s1 = "M1"; break;
 1097             case PG(0) + NC(0) + STR1(1): *brand_pre = "AMD";                                      s1 = "V";  break;
 1098             case PG(0) + NC(1) + STR1(0): *brand_pre = "AMD Turion(tm) II Ultra Dual-Core Mobile"; s1 = "M6"; break;
 1099             case PG(0) + NC(1) + STR1(1): *brand_pre = "AMD Turion(tm) II Dual-Core Mobile";       s1 = "M5"; break;
 1100             case PG(0) + NC(1) + STR1(2): *brand_pre = "AMD Athlon(tm) II Dual-Core";              s1 = "M3"; break;
 1101             case PG(0) + NC(1) + STR1(3): *brand_pre = "AMD Turion(tm) II";                        s1 = "P";  break;
 1102             case PG(0) + NC(1) + STR1(4): *brand_pre = "AMD Athlon(tm) II";                        s1 = "P";  break;
 1103             case PG(0) + NC(1) + STR1(5): *brand_pre = "AMD Phenom(tm) II";                        s1 = "X";  break;
 1104             case PG(0) + NC(1) + STR1(6): *brand_pre = "AMD Phenom(tm) II";                        s1 = "N";  break;
 1105             case PG(0) + NC(1) + STR1(7): *brand_pre = "AMD Turion(tm) II";                        s1 = "N";  break;
 1106             case PG(0) + NC(1) + STR1(8): *brand_pre = "AMD Athlon(tm) II";                        s1 = "N";  break;
 1107             case PG(0) + NC(2) + STR1(2): *brand_pre = "AMD Phenom(tm) II";                        s1 = "P";  break;
 1108             case PG(0) + NC(2) + STR1(3): *brand_pre = "AMD Phenom(tm) II";                        s1 = "N";  break;
 1109             case PG(0) + NC(3) + STR1(1): *brand_pre = "AMD Phenom(tm) II";                        s1 = "P";  break;
 1110             case PG(0) + NC(3) + STR1(2): *brand_pre = "AMD Phenom(tm) II";                        s1 = "X";  break;
 1111             case PG(0) + NC(3) + STR1(3): *brand_pre = "AMD Phenom(tm) II";                        s1 = "N";  break;
 1112             default:                                                                               s1 = NULL; break;
 1113             }
 1114             /* 41322 3.74: table 19: String1 Values for S1g3 and S1g4 Processors */
 1115             switch (PG(pg) + NC(nc) + STR2(str2)) {
 1116             case PG(0) + NC(0) + STR2(1): s2 = "0 Processor";             break;
 1117             case PG(0) + NC(1) + STR2(2): s2 = "0 Dual-Core Processor";   break;
 1118             case PG(0) + NC(2) + STR2(2): s2 = "0 Triple-Core Processor"; break;
 1119             case PG(0) + NC(3) + STR2(1): s2 = "0 Quad-Core Processor";   break;
 1120             default:                      s2 = NULL;                      break;
 1121             }
 1122             break;
 1123          case 3:
 1124             /* 41322 3.74: table 20: String1 Values for G34r1 Processors */
 1125             switch (PG(pg) + NC(nc) + STR1(str1)) {
 1126             case PG(0) + NC(7)  + STR1(0): *brand_pre = "AMD Opteron(tm)";          s1 = "Processor 61"; break;
 1127             case PG(0) + NC(11) + STR1(0): *brand_pre = "AMD Opteron(tm)";          s1 = "Processor 61"; break;
 1128             case PG(1) + NC(7)  + STR1(1): *brand_pre = "Embedded AMD Opteron(tm)"; s1 = "Processor ";   break;
 1129             /* It sure is odd that there are no 0/7/1 or 0/11/1 cases here. */
 1130             default:                                                                s1 = NULL;           break;
 1131             }
 1132             /* 41322 3.74: table 21: String2 Values for G34r1 Processors */
 1133             switch (PG(pg) + NC(nc) + STR2(str2)) {
 1134             case PG(0) + NC(7)  + STR1(0): s2 = " HE"; break;
 1135             case PG(0) + NC(7)  + STR1(1): s2 = " SE"; break;
 1136             case PG(0) + NC(11) + STR1(0): s2 = " HE"; break;
 1137             case PG(0) + NC(11) + STR1(1): s2 = " SE"; break;
 1138             case PG(1) + NC(7)  + STR1(1): s2 = "QS";  break;
 1139             case PG(1) + NC(7)  + STR1(2): s2 = "KS";  break;
 1140             default:                       s2 = NULL;  break;
 1141             }
 1142             break;
 1143          case 4:
 1144             /* 41322 3.74: table 22: String1 Values for ASB2 Processors */
 1145             switch (PG(pg) + NC(nc) + STR1(str1)) {
 1146             case PG(0) + NC(0) + STR1(1): *brand_pre = "AMD Athlon(tm) II Neo"; s1 = "K";  break;
 1147             case PG(0) + NC(0) + STR1(2): *brand_pre = "AMD";                   s1 = "V";  break;
 1148             case PG(0) + NC(0) + STR1(3): *brand_pre = "AMD Athlon(tm) II Neo"; s1 = "R";  break;
 1149             case PG(0) + NC(1) + STR1(1): *brand_pre = "AMD Turion(tm) II Neo"; s1 = "K";  break;
 1150             case PG(0) + NC(1) + STR1(2): *brand_pre = "AMD Athlon(tm) II Neo"; s1 = "K";  break;
 1151             case PG(0) + NC(1) + STR1(3): *brand_pre = "AMD";                   s1 = "V";  break;
 1152             case PG(0) + NC(1) + STR1(4): *brand_pre = "AMD Turion(tm) II Neo"; s1 = "N";  break;
 1153             case PG(0) + NC(1) + STR1(5): *brand_pre = "AMD Athlon(tm) II Neo"; s1 = "N";  break;
 1154             default:                                                            s1 = NULL; break;
 1155             }
 1156             /* 41322 3.74: table 23: String2 Values for ASB2 Processors */
 1157             switch (PG(pg) + NC(nc) + STR2(str2)) {
 1158             case PG(0) + NC(0)  + STR1(1): s2 = "5 Processor";           break;
 1159             case PG(0) + NC(0)  + STR1(2): s2 = "L Processor";           break;
 1160             case PG(0) + NC(1)  + STR1(1): s2 = "5 Dual-Core Processor"; break;
 1161             case PG(0) + NC(1)  + STR1(2): s2 = "L Dual-Core Processor"; break;
 1162             default:                       s2 = NULL;                    break;
 1163             }
 1164             break;
 1165          case 5:
 1166             /* 41322 3.74: table 24: String1 Values for C32r1 Processors */
 1167             switch (PG(pg) + NC(nc) + STR1(str1)) {
 1168             case PG(0) + NC(3) + STR1(0): *brand_pre = "AMD Opteron(tm)";          s1 = "41"; break;
 1169             case PG(0) + NC(5) + STR1(0): *brand_pre = "AMD Opteron(tm)";          s1 = "41"; break;
 1170             case PG(1) + NC(3) + STR1(1): *brand_pre = "Embedded AMD Opteron(tm)"; s1 = " ";  break;
 1171             case PG(1) + NC(5) + STR1(1): *brand_pre = "Embedded AMD Opteron(tm)"; s1 = " ";  break;
 1172             /* It sure is odd that there are no 0/3/1 or 0/5/1 cases here. */
 1173             default:                                                               s1 = NULL; break;
 1174             }
 1175             /* 41322 3.74: table 25: String2 Values for C32r1 Processors */
 1176             /* 41322 3.74: table 25 */
 1177             switch (PG(pg) + NC(nc) + STR2(str2)) {
 1178             case PG(0) + NC(3) + STR1(0): s2 = " HE";   break;
 1179             case PG(0) + NC(3) + STR1(1): s2 = " EE";   break;
 1180             case PG(0) + NC(5) + STR1(0): s2 = " HE";   break;
 1181             case PG(0) + NC(5) + STR1(1): s2 = " EE";   break;
 1182             case PG(1) + NC(3) + STR1(1): s2 = "QS HE"; break;
 1183             case PG(1) + NC(3) + STR1(2): s2 = "LE HE"; break;
 1184             case PG(1) + NC(3) + STR1(3): s2 = "CL EE"; break;
 1185             case PG(1) + NC(5) + STR1(1): s2 = "KX HE"; break;
 1186             case PG(1) + NC(5) + STR1(2): s2 = "GL EE"; break;
 1187             default:                      s2 = NULL;    break;
 1188             }
 1189             break;
 1190          default:
 1191             s1 = NULL;
 1192             s2 = NULL;
 1193             break;
 1194          }
 1195       } else if (__F(stash->val_1_eax) == _XF(2) + _F(15)) {
 1196          /* Family 11h tables */
 1197          switch (pkgtype) {
 1198          case 2:
 1199             /* 41788 3.08: table 3: String1 Values for S1g2 Processors */
 1200             switch (PG(pg) + NC(nc) + STR1(str1)) {
 1201             case PG(0) + NC(0) + STR1(0): *brand_pre = "AMD Sempron(tm)";                          s1 = "SI-"; break;
 1202             case PG(0) + NC(0) + STR1(1): *brand_pre = "AMD Athlon(tm)";                           s1 = "QI-"; break;
 1203             case PG(0) + NC(1) + STR1(0): *brand_pre = "AMD Turion(tm) X2 Ultra Dual-Core Mobile"; s1 = "ZM-"; break;
 1204             case PG(0) + NC(1) + STR1(1): *brand_pre = "AMD Turion(tm) X2 Dual-Core Mobile";       s1 = "RM-"; break;
 1205             case PG(0) + NC(1) + STR1(2): *brand_pre = "AMD Athlon(tm) X2 Dual-Core";              s1 = "QL-"; break;
 1206             case PG(0) + NC(1) + STR1(3): *brand_pre = "AMD Sempron(tm) X2 Dual-Core";             s1 = "NI-"; break;
 1207             default:                                                                               s1 = NULL;  break;
 1208             }
 1209             /* 41788 3.08: table 4: String2 Values for S1g2 Processors */
 1210             switch (PG(pg) + NC(nc) + STR2(str2)) {
 1211             case PG(0) + NC(0) + STR2(0): s2 = "";   break;
 1212             case PG(0) + NC(1) + STR2(0): s2 = "";   break;
 1213             default:                      s2 = NULL; break;
 1214             }
 1215             break;
 1216          default:
 1217             s1 = NULL;
 1218             s2 = NULL;
 1219             break;
 1220          }
 1221       } else if (__F(stash->val_1_eax) == _XF(3) + _F(15)) {
 1222          partialmodel--;
 1223 
 1224          /* Family 12h tables */
 1225          switch (pkgtype) {
 1226          case 1:
 1227             /* 44739 3.10: table 6: String1 Values for FS1 Processors */ 
 1228             switch (PG(pg) + NC(nc) + STR1(str1)) {
 1229             case PG(0) + NC(1) + STR1(3): *brand_pre = "AMD"; s1 = "A4-33"; break;
 1230             case PG(0) + NC(1) + STR1(5): *brand_pre = "AMD"; s1 = "E2-30"; break;
 1231             case PG(0) + NC(3) + STR1(1): *brand_pre = "AMD"; s1 = "A8-35"; break;
 1232             case PG(0) + NC(3) + STR1(3): *brand_pre = "AMD"; s1 = "A6-34"; break;
 1233             default:                                          s1 = NULL;    break;
 1234             }
 1235             /* 44739 3.10: table 7: String2 Values for FS1 Processors */ 
 1236             switch (PG(pg) + NC(nc) + STR2(str2)) {
 1237             case PG(0) + NC(1) + STR2(1):  s2 = "M";  break;
 1238             case PG(0) + NC(1) + STR2(2):  s2 = "MX"; break;
 1239             case PG(0) + NC(3) + STR2(1):  s2 = "M";  break;
 1240             case PG(0) + NC(3) + STR2(2):  s2 = "MX"; break;
 1241             default:                       s2 = NULL; break;
 1242             }
 1243             break;
 1244          case 2:
 1245             /* 44739 3.10: table 8: String1 Values for FM1 Processors */ 
 1246             switch (PG(pg) + NC(nc) + STR1(str1)) {
 1247             case PG(0) + NC(1) + STR1(1):  *brand_pre = "AMD";                   s1 = "A4-33"; break;
 1248             case PG(0) + NC(1) + STR1(2):  *brand_pre = "AMD";                   s1 = "E2-32"; break;
 1249             case PG(0) + NC(1) + STR1(4):  *brand_pre = "AMD Athlon(tm) II X2";  s1 = "2";     break;
 1250             case PG(0) + NC(1) + STR1(5):  *brand_pre = "AMD";                   s1 = "A4-34"; break;
 1251             case PG(0) + NC(1) + STR1(12): *brand_pre = "AMD Sempron(tm) X2";    s1 = "1";     break;
 1252             case PG(0) + NC(2) + STR1(5):  *brand_pre = "AMD";                   s1 = "A6-35"; break;
 1253             case PG(0) + NC(3) + STR1(5):  *brand_pre = "AMD";                   s1 = "A8-38"; break;
 1254             case PG(0) + NC(3) + STR1(6):  *brand_pre = "AMD";                   s1 = "A6-36"; break;
 1255             case PG(0) + NC(3) + STR1(13): *brand_pre = "AMD Athlon(tm) II X4";  s1 = "6";     break;
 1256             default:                                                             s1 = NULL;    break;
 1257             }
 1258             /* 44739 3.10: table 9: String2 Values for FM1 Processors */ 
 1259             switch (PG(pg) + NC(nc) + STR2(str2)) {
 1260             case PG(0) + NC(1) + STR2(1):  s2 = " APU with Radeon(tm) HD Graphics"; break;
 1261             case PG(0) + NC(1) + STR2(2):  s2 = " Dual-Core Processor";             break;
 1262             case PG(0) + NC(2) + STR2(1):  s2 = " APU with Radeon(tm) HD Graphics"; break;
 1263             case PG(0) + NC(3) + STR2(1):  s2 = " APU with Radeon(tm) HD Graphics"; break;
 1264             case PG(0) + NC(3) + STR2(3):  s2 = " Quad-Core Processor";             break;
 1265             default:                       s2 = NULL;                               break;
 1266             }
 1267             break;
 1268          default:
 1269             s1 = NULL;
 1270             s2 = NULL;
 1271             break;
 1272          }
 1273       } else if (__F(stash->val_1_eax) == _XF(5) + _F(15)) {
 1274          partialmodel--;
 1275 
 1276          /* Family 14h Models 00h-0Fh tables */
 1277          switch (pkgtype) {
 1278          case 0:
 1279             /* 47534 3.00: table 4: String1 Values for FT1 Processors */
 1280             switch (PG(pg) + NC(nc) + STR1(str1)) {
 1281             case PG(0) + NC(0) + STR1(1): *brand_pre = "AMD"; s1 = "C-";   break;
 1282             case PG(0) + NC(0) + STR1(2): *brand_pre = "AMD"; s1 = "E-";   break;
 1283             case PG(0) + NC(0) + STR1(4): *brand_pre = "AMD"; s1 = "G-T";  break;
 1284             case PG(0) + NC(1) + STR1(1): *brand_pre = "AMD"; s1 = "C-";   break;
 1285             case PG(0) + NC(1) + STR1(2): *brand_pre = "AMD"; s1 = "E-";   break;
 1286             case PG(0) + NC(1) + STR1(3): *brand_pre = "AMD"; s1 = "Z-";   break;
 1287             case PG(0) + NC(1) + STR1(4): *brand_pre = "AMD"; s1 = "G-T";  break;
 1288             case PG(0) + NC(1) + STR1(5): *brand_pre = "AMD"; s1 = "E1-1"; break;
 1289             case PG(0) + NC(1) + STR1(6): *brand_pre = "AMD"; s1 = "E2-1"; break;
 1290             case PG(0) + NC(1) + STR1(7): *brand_pre = "AMD"; s1 = "E2-2"; break;
 1291             default:                                          s1 = NULL;   break;
 1292             }
 1293             /* 47534 3.00: table 5: String2 Values for FT1 Processors */
 1294             switch (PG(pg) + NC(nc) + STR2(str2)) {
 1295             case PG(0) + NC(0) + STR2(1):  s2 = "";   break;
 1296             case PG(0) + NC(0) + STR2(2):  s2 = "0";  break;
 1297             case PG(0) + NC(0) + STR2(3):  s2 = "5";  break;
 1298             case PG(0) + NC(0) + STR2(4):  s2 = "0x"; break;
 1299             case PG(0) + NC(0) + STR2(5):  s2 = "5x"; break;
 1300             case PG(0) + NC(0) + STR2(6):  s2 = "x";  break;
 1301             case PG(0) + NC(0) + STR2(7):  s2 = "L";  break;
 1302             case PG(0) + NC(0) + STR2(8):  s2 = "N";  break;
 1303             case PG(0) + NC(0) + STR2(9):  s2 = "R";  break;
 1304             case PG(0) + NC(0) + STR2(10): s2 = "0";  break;
 1305             case PG(0) + NC(0) + STR2(11): s2 = "5";  break;
 1306             case PG(0) + NC(0) + STR2(12): s2 = "";   break;
 1307             case PG(0) + NC(0) + STR2(13): s2 = "0D"; break;
 1308             case PG(0) + NC(1) + STR2(1):  s2 = "";   break;
 1309             case PG(0) + NC(1) + STR2(2):  s2 = "0";  break;
 1310             case PG(0) + NC(1) + STR2(3):  s2 = "5";  break;
 1311             case PG(0) + NC(1) + STR2(4):  s2 = "0x"; break;
 1312             case PG(0) + NC(1) + STR2(5):  s2 = "5x"; break;
 1313             case PG(0) + NC(1) + STR2(6):  s2 = "x";  break;
 1314             case PG(0) + NC(1) + STR2(7):  s2 = "L";  break;
 1315             case PG(0) + NC(1) + STR2(8):  s2 = "N";  break;
 1316             case PG(0) + NC(1) + STR2(9):  s2 = "0";  break;
 1317             case PG(0) + NC(1) + STR2(10): s2 = "5";  break;
 1318             case PG(0) + NC(1) + STR2(11): s2 = "";   break;
 1319             case PG(0) + NC(1) + STR2(12): s2 = "E";  break;
 1320             case PG(0) + NC(1) + STR2(13): s2 = "0D"; break;
 1321             default:                       s2 = NULL; break;
 1322             }
 1323             break;
 1324          default:
 1325             s1 = NULL;
 1326             s2 = NULL;
 1327             break;
 1328          }
 1329       } else {
 1330          s1 = NULL;
 1331          s2 = NULL;
 1332       }
 1333 
 1334 #undef NC
 1335 #undef PG
 1336 #undef STR1
 1337 #undef STR2
 1338 
 1339       if (s1 != NULL) {
 1340          char*  p = proc;
 1341          p += sprintf(p, "%s%02d", s1, partialmodel);
 1342          if (s2) sprintf(p, "%s", s2);
 1343       }
 1344    }
 1345 }
 1346 
 1347 static void
 1348 decode_override_brand(code_stash_t*  stash)
 1349 {
 1350    if ((stash->vendor == VENDOR_AMD 
 1351         || stash->vendor == VENDOR_HYGON)
 1352        && strstr(stash->brand, "model unknown") != NULL) {
 1353       /*
 1354       ** AMD has this exotic architecture where the BIOS decodes the brand
 1355       ** string from tables and feeds it back into the CPU via MSR's.  If an old
 1356       ** BIOS cannot understand a new CPU, it uses the string "model unknown".
 1357       ** In this case, I use my own copies of tables to deduce the brand string
 1358       ** and decode that.
 1359       */
 1360       const char*  brand_pre;
 1361       const char*  brand_post;
 1362       char         proc[96];
 1363       decode_amd_model(stash, &brand_pre, &brand_post, proc);
 1364       if (brand_pre != NULL) {
 1365          char*  b = stash->override_brand;
 1366          b += sprintf(b, "%s %s", brand_pre, proc);
 1367          if (brand_post != NULL) sprintf(b, " %s", brand_post);
 1368       }
 1369    }
 1370 }
 1371 
 1372 static void
 1373 print_override_brand(code_stash_t*  stash)
 1374 {
 1375    if (stash->override_brand[0] != '\0') {
 1376       printf("   (override brand synth) = %s\n", stash->override_brand);
 1377    }
 1378 }
 1379 
 1380 static void
 1381 stash_intel_cache(code_stash_t*  stash,
 1382                   unsigned char  value)
 1383 {
 1384    switch (value) {
 1385    case 0x42: stash->L2_4w_256K   = TRUE; break;
 1386    case 0x43: stash->L2_4w_512K   = TRUE; break;
 1387    case 0x44: stash->L2_4w_1Mor2M = TRUE; break;
 1388    case 0x45: stash->L2_4w_1Mor2M = TRUE; break;
 1389    case 0x80: stash->L2_8w_512K   = TRUE; break;
 1390    case 0x82: stash->L2_8w_256K   = TRUE; break;
 1391    case 0x83: stash->L2_8w_512K   = TRUE; break;
 1392    case 0x84: stash->L2_8w_1Mor2M = TRUE; break;
 1393    case 0x85: stash->L2_8w_1Mor2M = TRUE; break;
 1394    }
 1395 
 1396    switch (value) {
 1397    case 0x45:
 1398    case 0x7d:
 1399    case 0x85:
 1400       stash->L2_2M = TRUE; 
 1401       break;
 1402    }
 1403 
 1404    switch (value) {
 1405    case 0x4e:
 1406       stash->L2_6M = TRUE; 
 1407       break;
 1408    }
 1409 
 1410    switch (value) {
 1411    case 0x22:
 1412    case 0x23:
 1413    case 0x25:
 1414    case 0x29:
 1415    case 0x46:
 1416    case 0x47:
 1417    case 0x49:
 1418    case 0x4a:
 1419    case 0x4b:
 1420    case 0x4c:
 1421    case 0x4d:
 1422    case 0x88:
 1423    case 0x89:
 1424    case 0x8a:
 1425    case 0x8d:
 1426    case 0xd0:
 1427    case 0xd1:
 1428    case 0xd2:
 1429    case 0xd6:
 1430    case 0xd7:
 1431    case 0xd8:
 1432    case 0xdc:
 1433    case 0xdd:
 1434    case 0xde:
 1435    case 0xe2:
 1436    case 0xe3:
 1437    case 0xe4:
 1438    case 0xea:
 1439    case 0xeb:
 1440    case 0xec:
 1441       stash->L3 = TRUE;
 1442       break;
 1443    }
 1444 
 1445    switch (value) {
 1446    case 0x21:
 1447    case 0x3c:
 1448    case 0x42:
 1449    case 0x7a:
 1450    case 0x7e:
 1451    case 0x82:
 1452       stash->L2_256K = TRUE;
 1453       break;
 1454    }
 1455 
 1456    switch (value) {
 1457    case 0x3e:
 1458    case 0x43:
 1459    case 0x7b:
 1460    case 0x7f:
 1461    case 0x83:
 1462    case 0x86:
 1463       stash->L2_512K = TRUE;
 1464       break;
 1465    }
 1466 }
 1467 
 1468 static void
 1469 decode_brand_id_stash(code_stash_t*  stash)
 1470 {
 1471    unsigned int  val_1_eax = stash->val_1_eax;
 1472    unsigned int  val_1_ebx = stash->val_1_ebx;
 1473 
 1474    switch (__B(val_1_ebx)) {
 1475    case _B(0):  break;
 1476    case _B(1):  stash->bri.desktop_celeron = TRUE; break;
 1477    case _B(2):  stash->bri.desktop_pentium = TRUE; break;
 1478    case _B(3):  if ( __FMS(val_1_eax) == _FMS(0,6, 0,11, 1)) {
 1479                    stash->bri.desktop_celeron = TRUE;
 1480                 } else {
 1481                    stash->bri.xeon = TRUE;
 1482                 }
 1483                 break;
 1484    case _B(4):  stash->bri.desktop_pentium = TRUE; break;
 1485    case _B(6):  stash->bri.desktop_pentium = TRUE; break;
 1486    case _B(7):  stash->bri.desktop_celeron = TRUE; break;
 1487    case _B(8):  stash->bri.desktop_pentium = TRUE; break;
 1488    case _B(9):  stash->bri.desktop_pentium = TRUE; break;
 1489    case _B(10): stash->bri.desktop_celeron = TRUE; break;
 1490    case _B(11): if (__FMS(val_1_eax) <= _FMS(0,15, 0,1, 2)) {
 1491                    stash->bri.xeon_mp = TRUE;
 1492                 } else {
 1493                    stash->bri.xeon = TRUE;
 1494                 }
 1495                 break;
 1496    case _B(12): stash->bri.xeon_mp         = TRUE; break;
 1497    case _B(14): if (__FMS(val_1_eax) <= _FMS(0,15, 0,1, 3)) {
 1498                    stash->bri.xeon = TRUE;
 1499                 } else {
 1500                    stash->bri.mobile_pentium_m = TRUE;
 1501                 }
 1502                 break;
 1503    case _B(15): if (__FM(val_1_eax) == _FM (0,15, 0,2)) {
 1504                    stash->bri.mobile_pentium_m = TRUE;
 1505                 } else {
 1506                    stash->bri.mobile_celeron = TRUE;
 1507                 }
 1508                 break;
 1509    case _B(16): stash->bri.desktop_celeron = TRUE; break;
 1510    case _B(17): stash->bri.mobile_pentium  = TRUE; break;
 1511    case _B(18): stash->bri.desktop_celeron = TRUE; break;
 1512    case _B(19): stash->bri.mobile_celeron  = TRUE; break;
 1513    case _B(20): stash->bri.desktop_celeron = TRUE; break;
 1514    case _B(21): stash->bri.mobile_pentium  = TRUE; break;
 1515    case _B(22): stash->bri.desktop_pentium = TRUE; break;
 1516    case _B(23): stash->bri.mobile_celeron  = TRUE; break;
 1517    default:     break;
 1518    }
 1519 }
 1520 
 1521 static void
 1522 decode_brand_string(const char*    brand,
 1523                     code_stash_t*  stash)
 1524 {
 1525    stash->br.mobile      = (strstr(brand, "Mobile") != NULL
 1526                             || strstr(brand, "mobile") != NULL);
 1527 
 1528    stash->br.celeron     = strstr(brand, "Celeron") != NULL;
 1529    stash->br.core        = strstr(brand, "Core(TM)") != NULL;
 1530    stash->br.pentium     = strstr(brand, "Pentium") != NULL;
 1531    stash->br.atom        = strstr(brand, "Atom") != NULL;
 1532    stash->br.xeon_mp     = (strstr(brand, "Xeon MP") != NULL
 1533                             || strstr(brand, "Xeon(TM) MP") != NULL
 1534                             || strstr(brand, "Xeon(R)") != NULL);
 1535    stash->br.xeon        = strstr(brand, "Xeon") != NULL;
 1536    stash->br.pentium_m   = strstr(brand, "Pentium(R) M") != NULL;
 1537    stash->br.pentium_d   = strstr(brand, "Pentium(R) D") != NULL;
 1538    stash->br.extreme     = strregexp(brand, " ?X[0-9][0-9][0-9][0-9]");
 1539    stash->br.generic     = strstr(brand, "Genuine Intel(R) CPU") != NULL;
 1540    stash->br.scalable    = (strstr(brand, "Bronze") != NULL
 1541                             || strstr(brand, "Silver") != NULL
 1542                             || strstr(brand, "Gold") != NULL
 1543                             || strstr(brand, "Platinum") != NULL);
 1544    stash->br.u_line      = (strregexp(brand, "Core.* [im][3579]-[0-9]*U")
 1545                             || strregexp(brand, "Pentium.* [0-9]*U")
 1546                             || strregexp(brand, "Celeron.* [0-9]*U"));
 1547    stash->br.y_line      = (strregexp(brand, "Core.* [im][3579]-[0-9]*Y")
 1548                             || strregexp(brand, "Pentium.* [0-9]*Y")
 1549                             || strregexp(brand, "Celeron.* [0-9]*Y"));
 1550    stash->br.g_line      = strregexp(brand, "Core.* [im][3579]-[0-9]*G");
 1551    stash->br.i_8000      = strregexp(brand, "Core.* [im][3579]-8[0-9][0-9][0-9]");
 1552    stash->br.i_10000     = strregexp(brand, "Core.* i[3579]-10[0-9][0-9][0-9]");
 1553    stash->br.cc150       = strregexp(brand, "CC150");
 1554 
 1555    stash->br.athlon_lv   = strstr(brand, "Athlon(tm) XP-M (LV)") != NULL;
 1556    stash->br.athlon_xp   = (strstr(brand, "Athlon(tm) XP") != NULL
 1557                             || strstr(brand, "Athlon(TM) XP") != NULL);
 1558    stash->br.duron       = strstr(brand, "Duron") != NULL;
 1559    stash->br.athlon      = strstr(brand, "Athlon") != NULL;
 1560    stash->br.sempron     = strstr(brand, "Sempron") != NULL;
 1561    stash->br.phenom      = strstr(brand, "Phenom") != NULL;
 1562    stash->br.series      = strstr(brand, "Series") != NULL;
 1563    stash->br.a_series    = (strstr(brand, "AMD A") != NULL
 1564                             || strstr(brand, "AMD PRO A") != NULL);
 1565    stash->br.c_series    = strstr(brand, "AMD C") != NULL;
 1566    stash->br.e_series    = strstr(brand, "AMD E") != NULL;
 1567    stash->br.g_series    = strstr(brand, "AMD G") != NULL;
 1568    stash->br.r_series    = strstr(brand, "AMD R") != NULL;
 1569    stash->br.z_series    = strstr(brand, "AMD Z") != NULL;
 1570    stash->br.geode       = strstr(brand, "Geode") != NULL;
 1571    stash->br.turion      = strstr(brand, "Turion") != NULL;
 1572    stash->br.neo         = strstr(brand, "Neo") != NULL;
 1573    stash->br.athlon_fx   = strstr(brand, "Athlon(tm) 64 FX") != NULL;
 1574    stash->br.athlon_mp   = strstr(brand, "Athlon(tm) MP") != NULL;
 1575    stash->br.duron_mp    = strstr(brand, "Duron(tm) MP") != NULL;
 1576    stash->br.opteron     = strstr(brand, "Opteron") != NULL;
 1577    stash->br.fx          = strstr(brand, "AMD FX") != NULL;
 1578    stash->br.firepro     = strstr(brand, "Firepro") != NULL; // total guess
 1579    stash->br.ultra       = strstr(brand, "Ultra") != NULL;
 1580    stash->br.t_suffix    = strregexp(brand, "[0-9][0-9][0-9][0-9]T");
 1581    stash->br.ryzen       = strstr(brand, "Ryzen") != NULL;
 1582    stash->br.epyc        = strstr(brand, "EPYC") != NULL;
 1583    stash->br.epyc_3000   = strregexp(brand, "EPYC 3[0-9][0-9][0-9]");
 1584 
 1585    stash->br.embedded    = strstr(brand, "Embedded") != NULL;
 1586    if (strstr(brand, "Dual Core") != NULL
 1587        || strstr(brand, " X2 ") != NULL) {
 1588       stash->br.cores = 2;
 1589    } else if (strstr(brand, "Triple-Core") != NULL
 1590               || strstr(brand, " X3 ") != NULL) {
 1591       stash->br.cores = 3;
 1592    } else if (strstr(brand, "Quad-Core") != NULL
 1593               || strstr(brand, " X4 ") != NULL) {
 1594       stash->br.cores = 4;
 1595    } else if (strstr(brand, "Six-Core") != NULL
 1596               || strstr(brand, " X6 ") != NULL) {
 1597       stash->br.cores = 6;
 1598    } else {
 1599       stash->br.cores = 0; // means unspecified by the brand string
 1600    }
 1601 
 1602    stash->br.mediagx     = strstr(brand, "MediaGXtm") != NULL;
 1603 
 1604    stash->br.c7          = strstr(brand, "C7") != NULL;
 1605    stash->br.c7m         = strstr(brand, "C7-M") != NULL;
 1606    stash->br.c7d         = strstr(brand, "C7-D") != NULL;
 1607    stash->br.eden        = strstr(brand, "Eden") != NULL;
 1608    stash->br.zhaoxin     = strstr(brand, "ZHAOXIN") != NULL;
 1609 }
 1610 
 1611 static void
 1612 decode_brand_stash(code_stash_t*  stash)
 1613 {
 1614    if (stash->override_brand[0] != '\0') {
 1615       decode_brand_string(stash->override_brand, stash);
 1616    } else {
 1617       decode_brand_string(stash->brand, stash);
 1618    }
 1619 }
 1620 
 1621 /*
 1622 ** Query macros are used in the synth tables to disambiguate multiple chips
 1623 ** with the same family, model, and/or stepping.
 1624 */
 1625 
 1626 #define is_intel      (stash->vendor == VENDOR_INTEL)
 1627 #define is_amd        (stash->vendor == VENDOR_AMD)
 1628 #define is_cyrix      (stash->vendor == VENDOR_CYRIX)
 1629 #define is_via        (stash->vendor == VENDOR_VIA)
 1630 #define is_transmeta  (stash->vendor == VENDOR_TRANSMETA)
 1631 #define is_mobile     (stash->br.mobile)
 1632 
 1633 /*
 1634 ** Intel major queries:
 1635 **
 1636 ** d? = think "desktop"
 1637 ** s? = think "server" (multiprocessor)
 1638 ** M? = think "mobile"
 1639 ** X? = think "Extreme Edition"
 1640 ** L? = think "Line"
 1641 **
 1642 ** ?G = think generic CPU
 1643 ** ?P = think Pentium
 1644 ** ?C = think Celeron
 1645 ** ?a = think Atom
 1646 ** ?X = think Xeon
 1647 ** ?M = think Xeon MP / Pentium M
 1648 ** ?c = think Core
 1649 ** ?d = think Pentium D
 1650 ** ?S = think Scalable (Bronze/Silver/Gold/Platinum)
 1651 */
 1652 #define dG (is_intel && !is_mobile && stash->br.generic)
 1653 #define dP ((is_intel && stash->br.pentium) \
 1654             || stash->bri.desktop_pentium)
 1655 #define dC ((is_intel && !is_mobile && stash->br.celeron) \
 1656             || stash->bri.desktop_celeron)
 1657 #define da (is_intel && stash->br.atom) 
 1658 #define dd (is_intel && stash->br.pentium_d)
 1659 #define TODD_WAS_HERE
 1660 #ifdef TODD_WAS_HERE
 1661 #define dc (is_intel && !is_mobile && stash->br.core)
 1662 #else
 1663 #define dc (is_intel && !is_mobile && (stash->br.core || stash->br.generic))
 1664 #endif
 1665 #define sX ((is_intel && stash->br.xeon) || stash->bri.xeon)
 1666 #define sM ((is_intel && stash->br.xeon_mp) \
 1667             || stash->bri.xeon_mp)
 1668 #define sS (is_intel && stash->br.xeon && stash->br.scalable)
 1669 #define MP ((is_intel && is_mobile && stash->br.pentium) \
 1670             || stash->bri.mobile_pentium)
 1671 #define MC ((is_intel && is_mobile && stash->br.celeron) \
 1672             || stash->bri.mobile_celeron)
 1673 #define MM ((is_intel && stash->br.pentium_m)\
 1674             || stash->bri.mobile_pentium_m)
 1675 #define Mc (is_intel && is_mobile && stash->br.core)
 1676 #define Xc (is_intel && stash->br.extreme)
 1677 #define LU (is_intel && stash->br.u_line)
 1678 #define LY (is_intel && stash->br.y_line)
 1679 #define LG (is_intel && stash->br.g_line)
 1680 #define UC (dC && stash->br.u_line)
 1681 #define UP (dP && stash->br.u_line)
 1682 #define YC (dC && stash->br.y_line)
 1683 #define YP (dP && stash->br.y_line)
 1684 #define d1 (is_intel && stash->br.cc150)
 1685 
 1686 /* 
 1687 ** Intel special cases 
 1688 */
 1689 /* Pentium II Xeon (Deschutes), distinguished from Pentium II (Deschutes) */
 1690 #define xD (stash->L2_4w_1Mor2M)
 1691 /* Mobile Pentium II (Deschutes), distinguished from Pentium II (Deschutes) */
 1692 #define mD (stash->L2_4w_256K)
 1693 /* Intel Celeron (Deschutes), distinguished from  Pentium II (Deschutes) */
 1694 #define cD (!stash->L2_4w_1Mor2M && !stash->L2_4w_512K && !stash->L2_4w_256K)
 1695 /* Pentium III Xeon (Katmai), distinguished from Pentium III (Katmai) */
 1696 #define xK (stash->L2_4w_1Mor2M || stash->L2_8w_1Mor2M)
 1697 /* Pentium II (Katmai), verified, so distinguished from fallback case */
 1698 #define pK ((stash->L2_4w_512K || stash->L2_8w_256K || stash->L2_8w_512K) \
 1699             && !stash->L2_4w_1Mor2M && !stash->L2_8w_1Mor2M)
 1700 /* Irwindale, distinguished from Nocona */
 1701 #define sI (sX && stash->L2_2M)
 1702 /* Potomac, distinguished from Cranford */
 1703 #define sP (sM && stash->L3)
 1704 /* Allendale, distinguished from Conroe */
 1705 #define dL (dc && stash->L2_2M)
 1706 /* Dual-Core Xeon Processor 5100 (Woodcrest B1) pre-production,
 1707    distinguished from Core 2 Duo (Conroe B1) */
 1708 #define QW (dG && stash->br.generic \
 1709             && (stash->mp.cores == 4 \
 1710                 || (stash->mp.cores == 2 && stash->mp.hyperthreads == 2)))
 1711 /* Core Duo (Yonah), distinguished from Core Solo (Yonah) */
 1712 #define DG (dG && stash->mp.cores == 2)
 1713 /* Core 2 Quad, distinguished from Core 2 Duo */
 1714 #define Qc (dc && stash->mp.cores == 4)
 1715 /* Core 2 Extreme (Conroe B1), distinguished from Core 2 Duo (Conroe B1) */
 1716 #define XE (dc && strstr(stash->brand, " E6800") != NULL)
 1717 /* Quad-Core Xeon, distinguished from Xeon; and
 1718    Xeon Processor 3300, distinguished from Xeon Processor 3100 */
 1719 #define sQ (sX && stash->mp.cores == 4)
 1720 /* Xeon Processor 7000, distinguished from Xeon */
 1721 #define IS_VMX(val_1_ecx)  (BIT_EXTRACT_LE((val_1_ecx), 5, 6))
 1722 #define s7 (sX && IS_VMX(stash->val_1_ecx))
 1723 /* Wolfdale C0/E0, distinguished from Wolfdale M0/R0 */
 1724 #define de (dc && stash->L2_6M)
 1725 /* Penryn C0/E0, distinguished from Penryn M0/R0 */
 1726 #define Me (Mc && stash->L2_6M)
 1727 /* Yorkfield C1/E0, distinguished from Yorkfield M1/E0 */
 1728 #define Qe (Qc && stash->L2_6M)
 1729 /* Yorkfield E0, distinguished from Yorkfield R0 */
 1730 #define se (sQ && stash->L2_6M)
 1731 /* Amber Lake-Y, distinguished from Kaby Lake-Y */
 1732 #define Y8 (LY && stash->br.i_8000)
 1733 /* Comet Lake V1, distinguished from Whiskey Lake V0 */
 1734 #define UX (LU && stash->br.i_10000)
 1735 
 1736 /*
 1737 ** AMD major queries:
 1738 **
 1739 ** d? = think "desktop"
 1740 ** s? = think "server" (MP)
 1741 ** M? = think "mobile"
 1742 ** S? = think "Series"
 1743 ** T? = think "Tablet"
 1744 ** A? = think "any"
 1745 ** E? = think "Embedded"
 1746 **
 1747 ** ?A = think Athlon
 1748 ** ?X = think Athlon XP
 1749 ** ?L = think Athlon XP (LV)
 1750 ** ?E = think EPYC
 1751 ** ?f = think FX
 1752 ** ?F = think Athlon FX
 1753 ** ?D = think Duron
 1754 ** ?S = think Sempron
 1755 ** ?O = think Opteron
 1756 ** ?T = think Turion
 1757 ** ?U = think Turion Ultra
 1758 ** ?p = think Phenom
 1759 ** ?R = think Ryzen
 1760 ** ?s = think ?-Series
 1761 ** ?n = think Turion Neo
 1762 ** ?N = think Neo
 1763 */
 1764 #define dA (is_amd && !is_mobile && stash->br.athlon)
 1765 #define dX (is_amd && !is_mobile && stash->br.athlon_xp)
 1766 #define dF (is_amd && !is_mobile && stash->br.athlon_fx)
 1767 #define df (is_amd && !is_mobile && stash->br.fx)
 1768 #define dD (is_amd && !is_mobile && stash->br.duron)
 1769 #define dS (is_amd && !is_mobile && stash->br.sempron)
 1770 #define dp (is_amd && !is_mobile && stash->br.phenom)
 1771 #define dI (is_amd && !is_mobile && stash->br.firepro)
 1772 #define dR (is_amd && !is_mobile && stash->br.ryzen)
 1773 #define sO (is_amd && !is_mobile && stash->br.opteron)
 1774 #define sA (is_amd && !is_mobile && stash->br.athlon_mp)
 1775 #define sD (is_amd && !is_mobile && stash->br.duron_mp)
 1776 #define sE (is_amd && !is_mobile && stash->br.epyc)
 1777 #define MA (is_amd && is_mobile && stash->br.athlon)
 1778 #define MX (is_amd && is_mobile && stash->br.athlon_xp)
 1779 #define ML (is_amd && is_mobile && stash->br.athlon_lv)
 1780 #define MD (is_amd && is_mobile && stash->br.duron)
 1781 #define MS (is_amd && is_mobile && stash->br.sempron)
 1782 #define Mp (is_amd && is_mobile && stash->br.phenom)
 1783 #define Ms (is_amd && is_mobile && stash->br.series)
 1784 #define Mr (is_amd && is_mobile && stash->br.r_series)
 1785 #define MG (is_amd && stash->br.geode)
 1786 #define MT (is_amd && stash->br.turion)
 1787 #define MU (is_amd && stash->br.ultra)
 1788 #define Mn (is_amd && stash->br.turion && stash->br.neo)
 1789 #define MN (is_amd && stash->br.neo)
 1790 #define Sa (is_amd && !is_mobile && stash->br.a_series)
 1791 #define Sc (is_amd && !is_mobile && stash->br.c_series)
 1792 #define Se (is_amd && !is_mobile && stash->br.e_series)
 1793 #define Sg (is_amd && !is_mobile && stash->br.g_series)
 1794 #define Sr (is_amd && !is_mobile && stash->br.r_series)
 1795 #define Sz (is_amd && !is_mobile && stash->br.z_series)
 1796 #define Ta (is_amd && stash->br.t_suffix && stash->br.a_series)
 1797 #define Te (is_amd && stash->br.t_suffix && stash->br.e_series)
 1798 #define AR (is_amd && stash->br.ryzen)
 1799 #define ER (is_amd && stash->br.ryzen && stash->br.embedded)
 1800 #define EE (is_amd && stash->br.epyc_3000)
 1801 
 1802 /*
 1803 ** AMD special cases
 1804 */
 1805 static boolean is_amd_egypt_athens_8xx(const code_stash_t*  stash)
 1806 {
 1807    /*
 1808    ** This makes its determination based on the Processor model
 1809    ** logic from:
 1810    **    Revision Guide for AMD Athlon 64 and AMD Opteron Processors 
 1811    **    (25759 Rev 3.79), Constructing the Processor Name String.
 1812    ** See also decode_amd_model().
 1813    */
 1814 
 1815    if (stash->vendor == VENDOR_AMD && stash->br.opteron) {
 1816       switch (__FM(stash->val_1_eax)) {
 1817       case _FM(0,15, 2,1): /* Italy/Egypt */
 1818       case _FM(0,15, 2,5): /* Troy/Athens */
 1819          {
 1820             unsigned int  bti;
 1821 
 1822             if (__B(stash->val_1_ebx) != 0) {
 1823                bti = BIT_EXTRACT_LE(__B(stash->val_1_ebx), 5, 8) << 2;
 1824             } else if (BIT_EXTRACT_LE(stash->val_80000001_ebx, 0, 12) != 0) {
 1825                bti = BIT_EXTRACT_LE(stash->val_80000001_ebx, 6, 12);
 1826             } else {
 1827                return FALSE;
 1828             }
 1829 
 1830             switch (bti) {
 1831             case 0x10:
 1832             case 0x11:
 1833             case 0x12:
 1834             case 0x13:
 1835             case 0x2a:
 1836             case 0x30:
 1837             case 0x31:
 1838             case 0x39:
 1839             case 0x3c:
 1840             case 0x32:
 1841             case 0x33:
 1842                /* It's a 2xx */
 1843                return FALSE;
 1844             case 0x14:
 1845             case 0x15:
 1846             case 0x16:
 1847             case 0x17:
 1848             case 0x2b:
 1849             case 0x34:
 1850             case 0x35:
 1851             case 0x3a:
 1852             case 0x3d:
 1853             case 0x36:
 1854             case 0x37:
 1855                /* It's an 8xx */
 1856                return TRUE;
 1857             }
 1858          }
 1859       }
 1860    }
 1861 
 1862    return FALSE;
 1863 }
 1864 
 1865 /* Embedded Opteron, distinguished from Opteron (Barcelona & Shanghai) */
 1866 #define EO (sO && stash->br.embedded)
 1867 /* Opterons, distinguished by number of processors */
 1868 #define DO (sO && stash->br.cores == 2)
 1869 #define SO (sO && stash->br.cores == 6)
 1870 /* Athlons, distinguished by number of processors */
 1871 #define DA (dA && stash->br.cores == 2)
 1872 #define TA (dA && stash->br.cores == 3)
 1873 #define QA (dA && stash->br.cores == 4)
 1874 /* Phenoms distinguished by number of processors */
 1875 #define Dp (dp && stash->br.cores == 2)
 1876 #define Tp (dp && stash->br.cores == 3)
 1877 #define Qp (dp && stash->br.cores == 4)
 1878 #define Sp (dp && stash->br.cores == 6)
 1879 /* Semprons, distinguished by number of processors */
 1880 #define DS (dS  && stash->br.cores == 2)
 1881 /* Egypt, distinguished from Italy; and
 1882    Athens, distingushed from Troy */
 1883 #define s8 (sO && is_amd_egypt_athens_8xx(stash))
 1884 /* Thorton A2, distinguished from Barton A2 */
 1885 #define dt (dX && stash->L2_256K)
 1886 /* Manchester E6, distinguished from from Toledo E6 */
 1887 #define dm (dA && stash->L2_512K)
 1888 /* Propus, distinguished from Regor */
 1889 #define dr (dA && stash->L2_512K)
 1890 /* Trinidad, distinguished from Taylor */
 1891 #define Mt (MT && stash->L2_512K)
 1892 
 1893 /*
 1894 ** Cyrix major query
 1895 */
 1896 #define cm (is_cyrix && stash->br.mediagx)
 1897 
 1898 /*
 1899 ** VIA major query
 1900 */
 1901 #define v7 (is_via && stash->br.c7)
 1902 #define vM (is_via && stash->br.c7m)
 1903 #define vD (is_via && stash->br.c7d)
 1904 #define vE (is_via && stash->br.eden)
 1905 #define vZ (is_via && stash->br.zhaoxin)
 1906 
 1907 /*
 1908 ** Transmeta major queries
 1909 **
 1910 ** t2 = TMx200
 1911 ** t4 = TMx400
 1912 ** t5 = TMx500
 1913 ** t6 = TMx600
 1914 ** t8 = TMx800
 1915 */
 1916 #define tm_rev(rev) (is_transmeta \
 1917                      && (stash->transmeta_proc_rev & 0xffff0000) == rev)
 1918 /* TODO: Add cases for Transmeta Crusoe TM5700/TM5900 */
 1919 /* TODO: Add cases for Transmeta Efficeon */
 1920 #define t2 (tm_rev(0x01010000))
 1921 #define t4 (tm_rev(0x01020000) || (tm_rev(0x01030000) && stash->L2_4w_256K))
 1922 #define t5 ((tm_rev(0x01040000) || tm_rev(0x01040000)) && stash->L2_4w_256K)
 1923 #define t6 (tm_rev(0x01030000) && stash->L2_4w_512K)
 1924 #define t8 ((tm_rev(0x01040000) || tm_rev(0x01040000)) && stash->L2_4w_512K)
 1925 
 1926 static cstring
 1927 decode_vendor(vendor_t             vendor,
 1928               const code_stash_t*  stash)
 1929 {
 1930    switch (vendor) {
 1931    case VENDOR_INTEL:     return "Intel";
 1932    case VENDOR_AMD:       return "AMD";
 1933    case VENDOR_CYRIX:     return "Cyrix";
 1934    case VENDOR_VIA:       if (stash->br.zhaoxin) {
 1935                              return "Zhaoxin";
 1936                           } else {
 1937                              return "VIA"; 
 1938                           }
 1939    case VENDOR_TRANSMETA: return "Transmeta";
 1940    case VENDOR_UMC:       return "UMC";
 1941    case VENDOR_NEXGEN:    return "NexGen";
 1942    case VENDOR_RISE:      return "Rise";
 1943    case VENDOR_SIS:       return "SiS";
 1944    case VENDOR_NSC:       return "NSC";
 1945    case VENDOR_VORTEX:    return "Vortex";
 1946    case VENDOR_RDC:       return "RDC";
 1947    case VENDOR_HYGON:     return "Hygon";
 1948    case VENDOR_ZHAOXIN:   return "Zhaoxin";
 1949    case VENDOR_UNKNOWN:
 1950    default:
 1951       return NULL;
 1952    }
 1953 }
 1954 
 1955 #define ACT(...)  (__VA_ARGS__)
 1956 
 1957 typedef struct {
 1958    cstring  uarch;         // process-dependent name
 1959    cstring  family;        // process-neutral name:
 1960                            //    sometimes independent (e.g. Core)
 1961                            //    sometimes based on lead uarch (e.g. Nehalem)
 1962    cstring  phys;          // physical properties: die process, #pins, etc.
 1963    boolean  core_is_uarch; // for some uarches, the core names are based on the
 1964                            // uarch names, so the uarch name becomes redundant
 1965 } arch_t;
 1966 
 1967 static void
 1968 init_arch(arch_t*  arch)
 1969 {
 1970    arch->uarch         = NULL;
 1971    arch->family        = NULL;
 1972    arch->phys          = NULL;
 1973    arch->core_is_uarch = FALSE;
 1974 }
 1975 
 1976 static void
 1977 decode_uarch_intel(unsigned int  val,
 1978                    arch_t*       arch)
 1979 {
 1980    init_arch(arch);
 1981    
 1982    cstring*  u   = &arch->uarch;
 1983    cstring*  f   = &arch->family;
 1984    cstring*  p   = &arch->phys;
 1985    boolean*  ciu = &arch->core_is_uarch;
 1986 
 1987    // Intel calls "Whiskey Lake", "Amber Lake", and "Comet Lake" distinct
 1988    // uarch's optimized from "Kaby Lake".  That just leads to confusion and long
 1989    // uarch names with slashes.  Their families & models overlap, and just
 1990    // differ based on brand (based on target market):
 1991    //    (0,6),(8,14),9  = Kaby Lake      -or- Amber Lake-Y
 1992    //    (0,6),(8,14),11 = Whiskey Lake-U -or- Amber Lake-Y
 1993    //    (0,6),(8,14),12 = Whiskey Lake-U -or- Amber Lake-Y -or- Comet Lake-U
 1994    // If the only way to distinguish two uarch's is by brand, I am skeptical
 1995    // that they really are distinct uarch's!  This is analogous to the multitude
 1996    // of core names in pre-Sandy Bridge days.  So I am treating those 3 as
 1997    // distinct cores within the "Kaby Lake" uarch.  This reduces the number of
 1998    // uarches in the Skylake-based era to:
 1999    //
 2000    //    [Skylake]         = lead uarch in {Skylake} family
 2001    //       [Cascade Lake] = Skylake + DL Boost + spectre/meltdown fixes
 2002    //    [Kaby Lake]       = Skylake, 14nm+ (includes Whiskey, Amber, Comet)
 2003    //    [Coffee Lake]     = Kaby Lake, 14nm++, 1.5x CPUs/die
 2004    //       [Palm Cove]    = Coffee Lake, 10nm, AVX-512
 2005    //
 2006    // That is a more manageable set.
 2007    //
 2008    // NOTE: Ice Lake & Tiger Lake cores are in the separate Sunny Cove uarch.
 2009 
 2010    START;
 2011    F   (    0, 4,                                                               *f = "i486");          // *p depends on core
 2012    FM  (    0, 5,  0, 0,                                                        *f = "P5",             *p = ".8um");
 2013    FM  (    0, 5,  0, 1,                                                        *f = "P5",             *p = ".8um");
 2014    FM  (    0, 5,  0, 2,                                                        *f = "P5");
 2015    FM  (    0, 5,  0, 3,                                                        *f = "P5",             *p = ".6um");
 2016    FM  (    0, 5,  0, 4,                                                        *f = "P5 MMX");
 2017    FM  (    0, 5,  0, 7,                                                        *f = "P5 MMX");
 2018    FM  (    0, 5,  0, 8,                                                        *f = "P5 MMX",         *p = ".25um");
 2019    FM  (    0, 5,  0, 9,                                                        *f = "P5 MMX");
 2020    FM  (    0, 6,  0, 0,                                                        *f = "P6 Pentium II");
 2021    FM  (    0, 6,  0, 1,                                                        *f = "P6 Pentium II"); // *p depends on core
 2022    FM  (    0, 6,  0, 2,                                                        *f = "P6 Pentium II");
 2023    FM  (    0, 6,  0, 3,                                                        *f = "P6 Pentium II",  *p = ".35um");
 2024    FM  (    0, 6,  0, 4,                                                        *f = "P6 Pentium II");
 2025    FM  (    0, 6,  0, 5,                                                        *f = "P6 Pentium II",  *p = ".25um");
 2026    FM  (    0, 6,  0, 6,                                                        *f = "P6 Pentium II",  *p = "L2 cache");
 2027    FM  (    0, 6,  0, 7,                                                        *f = "P6 Pentium III", *p = ".25um");
 2028    FM  (    0, 6,  0, 8,                                                        *f = "P6 Pentium III", *p = ".18um");
 2029    FM  (    0, 6,  0, 9,                                                        *f = "P6 Pentium M",   *p = ".13um");
 2030    FM  (    0, 6,  0,10,                                                        *f = "P6 Pentium III", *p = ".18um");
 2031    FM  (    0, 6,  0,11,                                                        *f = "P6 Pentium III", *p = ".13um");
 2032    FM  (    0, 6,  0,13,         *u = "Dothan",                                 *f = "P6 Pentium M");  // *p depends on core
 2033    FM  (    0, 6,  0,14,         *u = "Yonah",                                  *f = "P6 Pentium M",   *p = "65nm");
 2034    FM  (    0, 6,  0,15,         *u = "Merom",                                  *f = "Core",           *p = "65nm");
 2035    FM  (    0, 6,  1, 5,         *u = "Dothan",                                 *f = "P6 Pentium M",   *p = "90nm");
 2036    FM  (    0, 6,  1, 6,         *u = "Merom",                                  *f = "Core",           *p = "65nm");
 2037    FM  (    0, 6,  1, 7,         *u = "Penryn",                                 *f = "Core",           *p = "45nm");
 2038    FM  (    0, 6,  1,10,         *u = "Nehalem",                                *f = "Nehalem",        *p = "45nm");
 2039    FM  (    0, 6,  1,12,         *u = "Bonnell",                                                       *p = "45nm");
 2040    FM  (    0, 6,  1,13,         *u = "Penryn",                                 *f = "Core",           *p = "45nm");
 2041    FM  (    0, 6,  1,14,         *u = "Nehalem",                                *f = "Nehalem",        *p = "45nm");
 2042    FM  (    0, 6,  1,15,         *u = "Nehalem",                                *f = "Nehalem",        *p = "45nm");
 2043    FM  (    0, 6,  2, 5,         *u = "Westmere",                               *f = "Nehalem",        *p = "32nm");
 2044    FM  (    0, 6,  2, 6,         *u = "Bonnell",                                                       *p = "45nm");
 2045    FM  (    0, 6,  2, 7,         *u = "Saltwell",                                                      *p = "32nm");
 2046    FM  (    0, 6,  2,10,         *u = "Sandy Bridge",              *ciu = TRUE, *f = "Sandy Bridge",   *p = "32nm");
 2047    FM  (    0, 6,  2,12,         *u = "Westmere",                               *f = "Nehalem",        *p = "32nm");
 2048    FM  (    0, 6,  2,13,         *u = "Sandy Bridge",              *ciu = TRUE, *f = "Sandy Bridge",   *p = "32nm");
 2049    FM  (    0, 6,  2,14,         *u = "Nehalem",                                *f = "Nehalem",        *p = "45nm");
 2050    FM  (    0, 6,  2,15,         *u = "Westmere",                               *f = "Nehalem",        *p = "32nm");
 2051    FM  (    0, 6,  3, 5,         *u = "Saltwell",                                                      *p = "14nm");
 2052    FM  (    0, 6,  3, 6,         *u = "Saltwell",                                                      *p = "32nm");
 2053    FM  (    0, 6,  3, 7,         *u = "Silvermont",                                                    *p = "22nm");
 2054    FM  (    0, 6,  3,10,         *u = "Ivy Bridge",                *ciu = TRUE, *f = "Sandy Bridge",   *p = "22nm");
 2055    FM  (    0, 6,  3,12,         *u = "Haswell",                   *ciu = TRUE, *f = "Haswell",        *p = "22nm");
 2056    FM  (    0, 6,  3,13,         *u = "Broadwell",                 *ciu = TRUE, *f = "Haswell",        *p = "14nm");
 2057    FM  (    0, 6,  3,14,         *u = "Ivy Bridge",                *ciu = TRUE, *f = "Sandy Bridge",   *p = "22nm");
 2058    FM  (    0, 6,  3,15,         *u = "Haswell",                   *ciu = TRUE, *f = "Haswell",        *p = "22nm");
 2059    FM  (    0, 6,  4, 5,         *u = "Haswell",                   *ciu = TRUE, *f = "Haswell",        *p = "22nm");
 2060    FM  (    0, 6,  4, 6,         *u = "Haswell",                   *ciu = TRUE, *f = "Haswell",        *p = "22nm");
 2061    FM  (    0, 6,  4, 7,         *u = "Broadwell",                 *ciu = TRUE, *f = "Haswell",        *p = "14nm");
 2062    FM  (    0, 6,  4,10,         *u = "Silvermont",                                                    *p = "22nm"); // no docs, but /proc/cpuinfo seen in wild
 2063    FM  (    0, 6,  4,12,         *u = "Airmont",                                                       *p = "14nm");
 2064    FM  (    0, 6,  4,13,         *u = "Silvermont",                                                    *p = "22nm");
 2065    FMS (    0, 6,  4,14,  8,     *u = "Kaby Lake",                              *f = "Skylake",        *p = "14nm");
 2066    FM  (    0, 6,  4,14,         *u = "Skylake",                   *ciu = TRUE, *f = "Skylake",        *p = "14nm");
 2067    FM  (    0, 6,  4,15,         *u = "Broadwell",                 *ciu = TRUE, *f = "Haswell",        *p = "14nm");
 2068    FMS (    0, 6,  5, 5,  6,     *u = "Cascade Lake",              *ciu = TRUE, *f = "Skylake",        *p = "14nm"); // no docs, but example from Greg Stewart
 2069    FMS (    0, 6,  5, 5,  7,     *u = "Cascade Lake",              *ciu = TRUE, *f = "Skylake",        *p = "14nm");
 2070    FMS (    0, 6,  5, 5, 10,     *u = "Cooper Lake",               *ciu = TRUE, *f = "Skylake",        *p = "14nm");
 2071    FM  (    0, 6,  5, 5,         *u = "Skylake",                   *ciu = TRUE, *f = "Skylake",        *p = "14nm");
 2072    FM  (    0, 6,  5, 6,         *u = "Broadwell",                 *ciu = TRUE, *f = "Haswell",        *p = "14nm");
 2073    FM  (    0, 6,  5, 7,         *u = "Knights Landing",           *ciu = TRUE,                        *p = "14nm");
 2074    FM  (    0, 6,  5,10,         *u = "Silvermont",                                                    *p = "22nm"); // no spec update; only MSR_CPUID_table* so far
 2075    FM  (    0, 6,  5,12,         *u = "Goldmont",                                                      *p = "14nm"); // no spec update for Atom; only MSR_CPUID_table* so far
 2076    FM  (    0, 6,  5,13,         *u = "Silvermont",                                                    *p = "22nm"); // no spec update; only MSR_CPUID_table* so far
 2077    FMS (    0, 6,  5,14,  8,     *u = "Kaby Lake",                              *f = "Skylake",        *p = "14nm");
 2078    FM  (    0, 6,  5,14,         *u = "Skylake",                   *ciu = TRUE, *f = "Skylake",        *p = "14nm");
 2079    FM  (    0, 6,  5,15,         *u = "Goldmont",                                                      *p = "14nm");
 2080    FM  (    0, 6,  6, 6,         *u = "Palm Cove",                              *f = "Skylake",        *p = "10nm"); // no spec update; only MSR_CPUID_table* so far
 2081    FM  (    0, 6,  6,10,         *u = "Sunny Cove",                             *f = "Sunny Cove",     *p = "10nm"); // no spec update; only MSR_CPUID_table* so far
 2082    FM  (    0, 6,  6,12,         *u = "Sunny Cove",                             *f = "Sunny Cove",     *p = "10nm"); // no spec update; only MSR_CPUID_table* so far
 2083    FM  (    0, 6,  7, 5,         *u = "Airmont",                                                       *p = "14nm"); // no spec update; whispers & rumors
 2084    FM  (    0, 6,  7,10,         *u = "Goldmont Plus",                                                 *p = "14nm");
 2085    FM  (    0, 6,  7,13,         *u = "Sunny Cove",                             *f = "Sunny Cove",     *p = "10nm"); // no spec update; only MSR_CPUID_table* so far
 2086    FM  (    0, 6,  7,14,         *u = "Sunny Cove",                             *f = "Sunny Cove",     *p = "10nm");
 2087    FM  (    0, 6,  8, 5,         *u = "Knights Mill",              *ciu = TRUE,                        *p = "14nm"); // no spec update; only MSR_CPUID_table* so far
 2088    FM  (    0, 6,  8, 6,         *u = "Tremont",                                                       *p = "10nm"); // LX*
 2089    FM  (    0, 6,  8,10,         *u = "Tremont",                                                       *p = "10nm"); // no spec update; LX*
 2090    FM  (    0, 6,  8,12,         *u = "Willow Cove",                            *f = "Sunny Cove",     *p = "10nm"); // found only on en.wikichip.org
 2091    FM  (    0, 6,  8,13,         *u = "Willow Cove",                            *f = "Sunny Cove",     *p = "10nm"); // LX*
 2092    FM  (    0, 6,  8,14,         *u = "Kaby Lake",                              *f = "Skylake",        *p = "14nm");
 2093    FM  (    0, 6,  8,15,         *u = "Sapphire Rapids",                        *f = "Sunny Cove",     *p = "10nm"); // LX*
 2094    FM  (    0, 6,  9, 6,         *u = "Tremont",                                                       *p = "10nm"); // LX*
 2095    FM  (    0, 6,  9, 7,         *u = "Golden Cove",                                                   *p = "10nm"); // LX*
 2096    FM  (    0, 6,  9,10,         *u = "Golden Cove",                                                   *p = "10nm"); // Coreboot*
 2097    FM  (    0, 6,  9,12,         *u = "Tremont",                                                       *p = "10nm"); // LX*
 2098    FM  (    0, 6,  9,13,         *u = "Sunny Cove",                             *f = "Sunny Cove",     *p = "10nm"); // LX*
 2099    FMS (    0, 6,  9,14,  9,     *u = "Kaby Lake",                              *f = "Skylake",        *p = "14nm");
 2100    FMS (    0, 6,  9,14, 10,     *u = "Coffee Lake",               *ciu = TRUE, *f = "Skylake",        *p = "14nm");
 2101    FMS (    0, 6,  9,14, 11,     *u = "Coffee Lake",               *ciu = TRUE, *f = "Skylake",        *p = "14nm");
 2102    FMS (    0, 6,  9,14, 12,     *u = "Coffee Lake",               *ciu = TRUE, *f = "Skylake",        *p = "14nm");
 2103    FMS (    0, 6,  9,14, 13,     *u = "Coffee Lake",               *ciu = TRUE, *f = "Skylake",        *p = "14nm");
 2104    FM  (    0, 6,  9,14,         *u = "Kaby Lake / Coffee Lake",                *f = "Skylake",        *p = "14nm");
 2105    FM  (    0, 6, 10, 5,         *u = "Kaby Lake",                              *f = "Skylake",        *p = "14nm"); // LX*
 2106    FM  (    0, 6, 10, 6,         *u = "Kaby Lake",                              *f = "Skylake",        *p = "14nm"); // no spec update; only instlatx64 example
 2107    FM  (    0, 6, 10, 7,         *u = "Rocket Lake",                            *f = "Sunny Cove",     *p = "14nm"); // LX*
 2108    F   (    0, 7,                *u = "Itanium");
 2109    FM  (    0,11,  0, 0,         *u = "Knights Ferry",             *ciu = TRUE, *f = "K1OM",           *p = "45nm"); // found only on en.wikichip.org
 2110    FM  (    0,11,  0, 1,         *u = "Knights Corner",            *ciu = TRUE, *f = "K1OM",           *p = "22nm");
 2111    FM  (    0,15,  0, 0,         *u = "Willamette",                             *f = "Netburst",       *p = ".18um");
 2112    FM  (    0,15,  0, 1,         *u = "Willamette",                             *f = "Netburst",       *p = ".18um");
 2113    FM  (    0,15,  0, 2,         *u = "Northwood",                              *f = "Netburst",       *p = ".13um");
 2114    FM  (    0,15,  0, 3,         *u = "Prescott",                               *f = "Netburst",       *p = "90nm");
 2115    FM  (    0,15,  0, 4,         *u = "Prescott",                               *f = "Netburst",       *p = "90nm");
 2116    FM  (    0,15,  0, 6,         *u = "Cedar Mill",                             *f = "Netburst",       *p = "65nm");
 2117    F   (    0,15,                                                               *f = "Netburst");
 2118    FM  (    1,15,  0, 0,         *u = "Itanium2",                                                      *p = ".18um");
 2119    FM  (    1,15,  0, 1,         *u = "Itanium2",                                                      *p = ".13um");
 2120    FM  (    1,15,  0, 2,         *u = "Itanium2",                                                      *p = ".13um");
 2121    F   (    1,15,                *u = "Itanium2");
 2122    F   (    2, 0,                *u = "Itanium2",                                                      *p = "90nm");
 2123    F   (    2, 1,                *u = "Itanium2");
 2124    DEFAULT                      ((void)NULL);
 2125 }
 2126 
 2127 static void
 2128 decode_uarch_amd(unsigned int  val,
 2129                  arch_t*       arch)
 2130 {
 2131    init_arch(arch);
 2132    
 2133    cstring*  u = &arch->uarch;
 2134    cstring*  p = &arch->phys;
 2135 
 2136    START;
 2137    FM  ( 0, 4,  0, 3,         *u = "Am486");
 2138    FM  ( 0, 4,  0, 7,         *u = "Am486");
 2139    FM  ( 0, 4,  0, 8,         *u = "Am486");
 2140    FM  ( 0, 4,  0, 9,         *u = "Am486");
 2141    F   ( 0, 4,                *u = "Am5x86");
 2142    FM  ( 0, 5,  0, 6,         *u = "K6",          *p = ".30um");
 2143    FM  ( 0, 5,  0, 7,         *u = "K6",          *p = ".25um"); // *p from sandpile.org
 2144    FM  ( 0, 5,  0,13,         *u = "K6",          *p = ".18um"); // *p from sandpile.org
 2145    F   ( 0, 5,                *u = "K6");
 2146    FM  ( 0, 6,  0, 1,         *u = "K7",          *p = ".25um");
 2147    FM  ( 0, 6,  0, 2,         *u = "K7",          *p = ".18um");
 2148    F   ( 0, 6,                *u = "K7");
 2149    FMS ( 0,15,  0, 4,  8,     *u = "K8",          *p = "754-pin, .13um");
 2150    FM  ( 0,15,  0, 4,         *u = "K8",          *p = "940-pin, .13um");
 2151    FM  ( 0,15,  0, 5,         *u = "K8",          *p = "940-pin, .13um");
 2152    FM  ( 0,15,  0, 7,         *u = "K8",          *p = "939-pin, .13um");
 2153    FM  ( 0,15,  0, 8,         *u = "K8",          *p = "754-pin, .13um");
 2154    FM  ( 0,15,  0,11,         *u = "K8",          *p = "939-pin, .13um");
 2155    FM  ( 0,15,  0,12,         *u = "K8",          *p = "754-pin, .13um");
 2156    FM  ( 0,15,  0,14,         *u = "K8",          *p = "754-pin, .13um");
 2157    FM  ( 0,15,  0,15,         *u = "K8",          *p = "939-pin, .13um");
 2158    FM  ( 0,15,  1, 4,         *u = "K8",          *p = "754-pin, 90nm");
 2159    FM  ( 0,15,  1, 5,         *u = "K8",          *p = "940-pin, 90nm");
 2160    FM  ( 0,15,  1, 7,         *u = "K8",          *p = "939-pin, 90nm");
 2161    FM  ( 0,15,  1, 8,         *u = "K8",          *p = "754-pin, 90nm");
 2162    FM  ( 0,15,  1,11,         *u = "K8",          *p = "939-pin, 90nm");
 2163    FM  ( 0,15,  1,12,         *u = "K8",          *p = "754-pin, 90nm");
 2164    FM  ( 0,15,  1,15,         *u = "K8",          *p = "939-pin, 90nm");
 2165    FM  ( 0,15,  2, 1,         *u = "K8",          *p = "940-pin, 90nm");
 2166    FM  ( 0,15,  2, 3,         *u = "K8",          *p = "939-pin, 90nm");
 2167    FM  ( 0,15,  2, 4,         *u = "K8",          *p = "754-pin, 90nm");
 2168    FM  ( 0,15,  2, 5,         *u = "K8",          *p = "940-pin, 90nm");
 2169    FM  ( 0,15,  2, 7,         *u = "K8",          *p = "939-pin, 90nm");
 2170    FM  ( 0,15,  2,11,         *u = "K8",          *p = "939-pin, 90nm");
 2171    FM  ( 0,15,  2,12,         *u = "K8",          *p = "754-pin, 90nm");
 2172    FM  ( 0,15,  2,15,         *u = "K8",          *p = "939-pin, 90nm");
 2173    FM  ( 0,15,  4, 1,         *u = "K8",          *p = "90nm");
 2174    FM  ( 0,15,  4, 3,         *u = "K8",          *p = "90nm");
 2175    FM  ( 0,15,  4, 8,         *u = "K8",          *p = "90nm");
 2176    FM  ( 0,15,  4,11,         *u = "K8",          *p = "90nm");
 2177    FM  ( 0,15,  4,12,         *u = "K8",          *p = "90nm");
 2178    FM  ( 0,15,  4,15,         *u = "K8",          *p = "90nm");
 2179    FM  ( 0,15,  5,13,         *u = "K8",          *p = "90nm");
 2180    FM  ( 0,15,  5,15,         *u = "K8",          *p = "90nm");
 2181    FM  ( 0,15,  6, 8,         *u = "K8",          *p = "65nm");
 2182    FM  ( 0,15,  6,11,         *u = "K8",          *p = "65nm");
 2183    FM  ( 0,15,  6,12,         *u = "K8",          *p = "65nm");
 2184    FM  ( 0,15,  6,15,         *u = "K8",          *p = "65nm");
 2185    FM  ( 0,15,  7,12,         *u = "K8",          *p = "65nm");
 2186    FM  ( 0,15,  7,15,         *u = "K8",          *p = "65nm");
 2187    FM  ( 0,15, 12, 1,         *u = "K8",          *p = "90nm");
 2188    FM  ( 1,15,  0, 0,         *u = "K10",         *p = "65nm"); // sandpile.org
 2189    FM  ( 1,15,  0, 2,         *u = "K10",         *p = "65nm");
 2190    FM  ( 1,15,  0, 4,         *u = "K10",         *p = "45nm");
 2191    FM  ( 1,15,  0, 5,         *u = "K10",         *p = "45nm");
 2192    FM  ( 1,15,  0, 6,         *u = "K10",         *p = "45nm");
 2193    FM  ( 1,15,  0, 8,         *u = "K10",         *p = "45nm");
 2194    FM  ( 1,15,  0, 9,         *u = "K10",         *p = "45nm");
 2195    FM  ( 1,15,  0,10,         *u = "K10",         *p = "45nm");
 2196    F   ( 2,15,                *u = "Puma 2008",   *p = "65nm");
 2197    F   ( 3,15,                *u = "K10",         *p = "32nm");
 2198    F   ( 5,15,                *u = "Bobcat",      *p = "40nm");
 2199    FM  ( 6,15,  0, 0,         *u = "Bulldozer",   *p = "32nm"); // instlatx64 engr sample
 2200    FM  ( 6,15,  0, 1,         *u = "Bulldozer",   *p = "32nm");
 2201    FM  ( 6,15,  0, 2,         *u = "Piledriver",  *p = "32nm");
 2202    FM  ( 6,15,  1, 0,         *u = "Piledriver",  *p = "32nm");
 2203    FM  ( 6,15,  1, 3,         *u = "Piledriver",  *p = "32nm");
 2204    FM  ( 6,15,  3, 0,         *u = "Steamroller", *p = "28nm");
 2205    FM  ( 6,15,  3, 8,         *u = "Steamroller", *p = "28nm");
 2206    FM  ( 6,15,  4, 0,         *u = "Steamroller", *p = "28nm"); // Software Optimization Guide (15h) says it has the same inst latencies as (6,15),(3,x).
 2207    FM  ( 6,15,  6, 0,         *u = "Excavator",   *p = "28nm"); // undocumented, but instlatx64 samples
 2208    FM  ( 6,15,  6, 5,         *u = "Excavator",   *p = "28nm"); // undocumented, but sample from Alexandros Couloumbis
 2209    FM  ( 6,15,  7, 0,         *u = "Excavator",   *p = "28nm");
 2210    FM  ( 7,15,  0, 0,         *u = "Jaguar",      *p = "28nm");
 2211    FM  ( 7,15,  2, 6,         *u = "Cato",        *p = "28nm"); // only instlatx64 example; engr sample?
 2212    FM  ( 7,15,  3, 0,         *u = "Puma 2014",   *p = "28nm");
 2213    FM  ( 8,15,  0, 0,         *u = "Zen",         *p = "14nm"); // instlatx64 engr sample
 2214    FM  ( 8,15,  0, 1,         *u = "Zen",         *p = "14nm");
 2215    FM  ( 8,15,  0, 8,         *u = "Zen+",        *p = "12nm");
 2216    FM  ( 8,15,  1, 1,         *u = "Zen",         *p = "14nm"); // found only on en.wikichip.org & instlatx64 examples
 2217    FM  ( 8,15,  1, 8,         *u = "Zen+",        *p = "12nm");
 2218    FM  ( 8,15,  2, 0,         *u = "Zen",         *p = "14nm");
 2219    FM  ( 8,15,  3, 1,         *u = "Zen 2",       *p = "7nm");  // found only on en.wikichip.org
 2220    FM  ( 8,15,  6, 0,         *u = "Zen 2",       *p = "7nm");
 2221    FM  ( 8,15,  7, 1,         *u = "Zen 2",       *p = "7nm");  // undocumented, but samples from Steven Noonan
 2222    F   (10,15,                *u = "Zen 3",       *p = "7nm");  // undocumented, LX*
 2223    DEFAULT                  ((void)NULL);
 2224 }
 2225 
 2226 static void
 2227 decode_uarch_cyrix(unsigned int  val,
 2228                    arch_t*       arch)
 2229 {
 2230    init_arch(arch);
 2231    
 2232    cstring*  u   = &arch->uarch;
 2233    boolean*  ciu = &arch->core_is_uarch;
 2234 
 2235    START;
 2236    F   (0, 5,                *u = "M1", *ciu = TRUE);
 2237    F   (0, 6,                *u = "M2", *ciu = TRUE);
 2238    DEFAULT                  ((void)NULL);
 2239 }
 2240 
 2241 static void
 2242 decode_uarch_via(unsigned int         val,
 2243                  arch_t*              arch,
 2244                  const code_stash_t*  stash)
 2245 {
 2246    init_arch(arch);
 2247    
 2248    cstring*  u   = &arch->uarch;
 2249    boolean*  ciu = &arch->core_is_uarch;
 2250    cstring*  p   = &arch->phys;
 2251 
 2252    START;
 2253    F   (0, 5,                *u = "WinChip",    *ciu = TRUE);
 2254    FM  (0, 6,  0, 6,         *u = "C3",         *ciu = TRUE,  *p = ".18um");
 2255    FM  (0, 6,  0, 7,         *u = "C3",         *ciu = TRUE); // *p depends on core
 2256    FM  (0, 6,  0, 8,         *u = "C3",         *ciu = TRUE,  *p = ".13um");
 2257    FM  (0, 6,  0, 9,         *u = "C3",         *ciu = TRUE,  *p = ".13um");
 2258    FM  (0, 6,  0,10,         *u = "C7",                       *p = "90nm");
 2259    FM  (0, 6,  0,13,         *u = "C7",                       *p = "90nm");
 2260    FMSQ(0, 6,  0,15, 14, vZ, *u = "ZhangJiang",               *p = "28nm");
 2261    FM  (0, 6,  0,15,         *u = "C7");                      // *p depends on core
 2262    FM  (0, 7,  0,11,         *u = "ZhangJiang",               *p = "28nm");
 2263    DEFAULT                  ((void)NULL);
 2264 }
 2265 
 2266 static void
 2267 decode_uarch_umc(unsigned int  val,
 2268                  arch_t*       arch)
 2269 {
 2270    init_arch(arch);
 2271    
 2272    cstring*  u   = &arch->uarch;
 2273    boolean*  ciu = &arch->core_is_uarch;
 2274 
 2275    START;
 2276    F   (0, 4,                *u = "486 U5", *ciu = TRUE);
 2277    DEFAULT                  ((void)NULL);
 2278 }
 2279 
 2280 static void
 2281 decode_uarch_nexgen(unsigned int  val,
 2282                     arch_t*       arch)
 2283 {
 2284    init_arch(arch);
 2285    
 2286    cstring*  u = &arch->uarch;
 2287 
 2288    START;
 2289    F   (0, 5,                *u = "Nx586");
 2290    DEFAULT                  ((void)NULL);
 2291 }
 2292 
 2293 static void
 2294 decode_uarch_rise(unsigned int  val,
 2295                   arch_t*       arch)
 2296 {
 2297    init_arch(arch);
 2298    
 2299    cstring*  u   = &arch->uarch;
 2300    boolean*  ciu = &arch->core_is_uarch;
 2301 
 2302    START;
 2303    F   (0, 5,                *u = "mP6", *ciu = TRUE);
 2304    DEFAULT                  ((void)NULL);
 2305 }
 2306 
 2307 static void
 2308 decode_uarch_transmeta(unsigned int  val,
 2309                        arch_t*       arch)
 2310 {
 2311    init_arch(arch);
 2312    
 2313    cstring*  u   = &arch->uarch;
 2314    boolean*  ciu = &arch->core_is_uarch;
 2315 
 2316    START;
 2317    F   (0, 5,                *u = "Crusoe",   *ciu = TRUE);
 2318    F   (0,15,                *u = "Efficeon", *ciu = TRUE);
 2319    DEFAULT                  ((void)NULL);
 2320 }
 2321 
 2322 static void
 2323 decode_uarch_sis(unsigned int  val,
 2324                  arch_t*       arch)
 2325 {
 2326    init_arch(arch);
 2327    
 2328    cstring*  u   = &arch->uarch;
 2329    boolean*  ciu = &arch->core_is_uarch;
 2330 
 2331    START;
 2332    F   (0, 5,                *u = "mP6", *ciu = TRUE);
 2333    DEFAULT                  ((void)NULL);
 2334 }
 2335 
 2336 static void
 2337 decode_uarch_hygon(unsigned int  val,
 2338                    arch_t*       arch)
 2339 {
 2340    init_arch(arch);
 2341    
 2342    cstring*  u = &arch->uarch;
 2343    cstring*  p = &arch->phys;
 2344 
 2345    START;
 2346    FM  (9,15,  0, 0,         *u = "Moksha", *p = "14nm");
 2347    DEFAULT                  ((void)NULL);
 2348 }
 2349 
 2350 static void
 2351 decode_uarch_zhaoxin(unsigned int  val,
 2352                      arch_t*       arch)
 2353 {
 2354    init_arch(arch);
 2355    
 2356    cstring*  u   = &arch->uarch;
 2357    boolean*  ciu = &arch->core_is_uarch;
 2358    cstring*  p   = &arch->phys;
 2359 
 2360    START;
 2361    FM  (0, 7,  1,11,         *u = "WuDaoKou", *ciu = TRUE, *p = "28nm");
 2362    FM  (0, 7,  3,11,         *u = "LuJiaZui", *ciu = TRUE, *p = "16nm");
 2363    DEFAULT                  ((void)NULL);
 2364 }
 2365 
 2366 #undef ACT
 2367 
 2368 static void
 2369 decode_uarch(unsigned int         val,
 2370              vendor_t             vendor,
 2371              const code_stash_t*  stash,
 2372              arch_t*              arch)
 2373 {
 2374    init_arch(arch);
 2375    
 2376    switch (vendor) {
 2377    case VENDOR_INTEL:
 2378       decode_uarch_intel(val, arch);
 2379       break;
 2380    case VENDOR_AMD:
 2381       decode_uarch_amd(val, arch);
 2382       break;
 2383    case VENDOR_CYRIX:
 2384       decode_uarch_cyrix(val, arch);
 2385       break;
 2386    case VENDOR_VIA:
 2387       decode_uarch_via(val, arch, stash);
 2388       break;
 2389    case VENDOR_TRANSMETA:
 2390       decode_uarch_transmeta(val, arch);
 2391       break;
 2392    case VENDOR_UMC:
 2393       decode_uarch_umc(val, arch);
 2394       break;
 2395    case VENDOR_NEXGEN:
 2396       decode_uarch_nexgen(val, arch);
 2397       break;
 2398    case VENDOR_RISE:
 2399       decode_uarch_rise(val, arch);
 2400       break;
 2401    case VENDOR_SIS:
 2402       decode_uarch_sis(val, arch);
 2403       break;
 2404    case VENDOR_HYGON:
 2405       decode_uarch_hygon(val, arch);
 2406       break;
 2407    case VENDOR_ZHAOXIN:
 2408       decode_uarch_zhaoxin(val, arch);
 2409       break;
 2410    case VENDOR_NSC:
 2411    case VENDOR_VORTEX:
 2412    case VENDOR_RDC:
 2413    case VENDOR_UNKNOWN:
 2414       break;
 2415    }
 2416 }
 2417 
 2418 static void
 2419 print_uarch(const code_stash_t*  stash)
 2420 {
 2421    arch_t  arch;
 2422    decode_uarch(stash->val_1_eax, stash->vendor, stash, &arch);
 2423    if (arch.uarch != NULL || arch.family != NULL || arch.phys != NULL) {
 2424       ccstring  vendor = decode_vendor(stash->vendor, stash);
 2425       printf("   (uarch synth) =");
 2426       if (vendor != NULL) {
 2427          printf(" %s", vendor);
 2428       }
 2429       if (arch.uarch != NULL) {
 2430          printf(" %s", arch.uarch);
 2431       }
 2432       if (arch.family != NULL) {
 2433          printf(" {%s}", arch.family);
 2434       }
 2435       if (arch.phys != NULL) {
 2436          printf(", %s", arch.phys);
 2437       }
 2438       printf("\n");
 2439    }
 2440 }
 2441 
 2442 static cstring
 2443 append_uarch(ccstring      synth,
 2444              unsigned int  val,
 2445              vendor_t      vendor)
 2446 {
 2447    if (synth != NULL) {
 2448       arch_t  arch;
 2449       decode_uarch(val, vendor, NULL, &arch);
 2450       if ((arch.uarch != NULL && !arch.core_is_uarch)
 2451           || arch.family != NULL
 2452           || arch.phys != NULL) {
 2453          static char  buffer[1024];
 2454          char*        ptr = buffer;
 2455 
 2456          ptr += sprintf(ptr, "%s", synth);
 2457 
 2458          if (arch.uarch != NULL && !arch.core_is_uarch) {
 2459             ptr += sprintf(ptr, " [%s]", arch.uarch);
 2460          }
 2461          if (arch.family != NULL) {
 2462             ptr += sprintf(ptr, " {%s}", arch.family);
 2463          }
 2464          if (arch.phys != NULL) {
 2465             ptr += sprintf(ptr, ", %s", arch.phys);
 2466          }
 2467          return buffer;
 2468       }
 2469    }
 2470 
 2471    return synth;
 2472 }
 2473 
 2474 static void
 2475 debug_queries(const code_stash_t*  stash)
 2476 {
 2477 #define DEBUGQ(q) printf("%s = %s\n", #q, (q)      ? "TRUE" : "FALSE")
 2478 #define DEBUGF(f) printf("%s = %s\n", #f, f(stash) ? "TRUE" : "FALSE")
 2479 
 2480    DEBUGQ(is_intel);
 2481    DEBUGQ(is_amd);
 2482    DEBUGQ(is_transmeta);
 2483    DEBUGQ(is_mobile);
 2484    DEBUGQ(MC);
 2485    DEBUGQ(Mc);
 2486    DEBUGQ(MP);
 2487    DEBUGQ(sM);
 2488    DEBUGQ(sX);
 2489    DEBUGQ(dC);
 2490    DEBUGQ(da);
 2491    DEBUGQ(MM);
 2492    DEBUGQ(dd);
 2493    DEBUGQ(dP);
 2494    DEBUGQ(Xc);
 2495    DEBUGQ(dc);
 2496    DEBUGQ(dG);
 2497 
 2498    DEBUGQ(xD);
 2499    DEBUGQ(mD);
 2500    DEBUGQ(cD);
 2501    DEBUGQ(xK);
 2502    DEBUGQ(pK);
 2503    DEBUGQ(sI);
 2504    DEBUGQ(sP);
 2505    DEBUGQ(dL);
 2506    DEBUGQ(QW);
 2507    DEBUGQ(DG);
 2508    DEBUGQ(Qc);
 2509    DEBUGQ(XE);
 2510    DEBUGQ(sQ);
 2511    DEBUGQ(s7);
 2512    DEBUGQ(de);
 2513    DEBUGQ(Me);
 2514    DEBUGQ(Qe);
 2515    DEBUGQ(se);
 2516 
 2517    DEBUGQ(dp);
 2518    DEBUGQ(dX);
 2519    DEBUGQ(dF);
 2520    DEBUGQ(df);
 2521    DEBUGQ(dD);
 2522    DEBUGQ(dS);
 2523    DEBUGQ(dR);
 2524    DEBUGQ(sO);
 2525    DEBUGQ(sA);
 2526    DEBUGQ(sD);
 2527    DEBUGQ(sE);
 2528    DEBUGQ(dD);
 2529    DEBUGQ(dA);
 2530    DEBUGQ(dS);
 2531    DEBUGQ(ML);
 2532    DEBUGQ(MX);
 2533    DEBUGQ(MD);
 2534    DEBUGQ(MA);
 2535    DEBUGQ(MS);
 2536    DEBUGQ(Mp);
 2537    DEBUGQ(Ms);
 2538    DEBUGQ(MG);
 2539    DEBUGQ(MT);
 2540    DEBUGQ(Mn);
 2541    DEBUGQ(MN);
 2542    DEBUGQ(Sa);
 2543 
 2544    DEBUGF(is_amd_egypt_athens_8xx);
 2545    DEBUGQ(EO);
 2546    DEBUGQ(DO);
 2547    DEBUGQ(SO);
 2548    DEBUGQ(DA);
 2549    DEBUGQ(TA);
 2550    DEBUGQ(QA);
 2551    DEBUGQ(Dp);
 2552    DEBUGQ(Tp);
 2553    DEBUGQ(Qp);
 2554    DEBUGQ(Sp);
 2555    DEBUGQ(DS);
 2556    DEBUGQ(s8);
 2557    DEBUGQ(dt);
 2558    DEBUGQ(dm);
 2559    DEBUGQ(dr);
 2560    DEBUGQ(Mt);
 2561 
 2562    DEBUGQ(t2);
 2563    DEBUGQ(t4);
 2564    DEBUGQ(t5);
 2565    DEBUGQ(t6);
 2566    DEBUGQ(t8);
 2567 
 2568 #undef DEBUGQ
 2569 #undef DEBUGF
 2570 }
 2571 
 2572 #define ACT(str)  (result = (str))
 2573 
 2574 static cstring
 2575 decode_synth_intel(unsigned int         val,  /* val_1_eax */
 2576                    const code_stash_t*  stash)
 2577 {
 2578    cstring  result = NULL;
 2579    
 2580    START;
 2581    FM  (    0, 4,  0, 0,         "Intel i80486DX-25/33, .18um"); // process from sandpile.org
 2582    FM  (    0, 4,  0, 1,         "Intel i80486DX-50, .18um"); // process from sandpile.org
 2583    FM  (    0, 4,  0, 2,         "Intel i80486SX, .18um"); // process from sandpile.org
 2584    FM  (    0, 4,  0, 3,         "Intel i80486DX/2");
 2585    FM  (    0, 4,  0, 4,         "Intel i80486SL, .8um");
 2586    FM  (    0, 4,  0, 5,         "Intel i80486SX/2, .8um");
 2587    FM  (    0, 4,  0, 7,         "Intel i80486DX/2-WB, .8um");
 2588    FM  (    0, 4,  0, 8,         "Intel i80486DX/4, .6um");
 2589    FM  (    0, 4,  0, 9,         "Intel i80486DX/4-WB, .6um");
 2590    F   (    0, 4,                "Intel i80486 (unknown model)");
 2591    FM  (    0, 5,  0, 0,         "Intel Pentium 60/66 A-step"); // no docs
 2592    // Intel docs (243326).
 2593    TFM (1,  0, 5,  0, 1,         "Intel Pentium 60/66 OverDrive for P5");
 2594    FMS (    0, 5,  0, 1,  3,     "Intel Pentium 60/66 (B1)");
 2595    FMS (    0, 5,  0, 1,  5,     "Intel Pentium 60/66 (C1)");
 2596    FMS (    0, 5,  0, 1,  7,     "Intel Pentium 60/66 (D1)");
 2597    FM  (    0, 5,  0, 1,         "Intel Pentium 60/66");
 2598    // Intel docs (242480).
 2599    TFM (1,  0, 5,  0, 2,         "Intel Pentium 75 - 200 OverDrive for P54C");
 2600    FMS (    0, 5,  0, 2,  1,     "Intel Pentium P54C 75 - 200 (B1)");
 2601    FMS (    0, 5,  0, 2,  2,     "Intel Pentium P54C 75 - 200 (B3)");
 2602    FMS (    0, 5,  0, 2,  4,     "Intel Pentium P54C 75 - 200 (B5)");
 2603    FMS (    0, 5,  0, 2,  5,     "Intel Pentium P54C 75 - 200 (C2/mA1)");
 2604    FMS (    0, 5,  0, 2,  6,     "Intel Pentium P54C 75 - 200 (E0)");
 2605    FMS (    0, 5,  0, 2, 11,     "Intel Pentium P54C 75 - 200 (cB1)");
 2606    FMS (    0, 5,  0, 2, 12,     "Intel Pentium P54C 75 - 200 (cC0)");
 2607    FM  (    0, 5,  0, 2,         "Intel Pentium P54C 75 - 200");
 2608    TFM (1,  0, 5,  0, 3,         "Intel Pentium OverDrive for i486 (P24T)"); // no docs
 2609    // Intel docs (242480).
 2610    TFM (1,  0, 5,  0, 4,         "Intel Pentium OverDrive for P54C");
 2611    FMS (    0, 5,  0, 4,  3,     "Intel Pentium MMX P55C (B1)");
 2612    FMS (    0, 5,  0, 4,  4,     "Intel Pentium MMX P55C (A3)");
 2613    FM  (    0, 5,  0, 4,         "Intel Pentium MMX P55C");
 2614    // Intel docs (242480).
 2615    FMS (    0, 5,  0, 7,  0,     "Intel Pentium MMX P54C 75 - 200 (A4)");
 2616    FM  (    0, 5,  0, 7,         "Intel Pentium MMX P54C 75 - 200");
 2617    // Intel docs (242480).
 2618    FMS (    0, 5,  0, 8,  1,     "Intel Pentium MMX P55C (Tillamook A0)");
 2619    FMS (    0, 5,  0, 8,  2,     "Intel Pentium MMX P55C (Tillamook B2)");
 2620    FM  (    0, 5,  0, 8,         "Intel Pentium MMX P55C (Tillamook)");
 2621    // Intel docs (329676) provides stepping names, but no numbers.
 2622    // However, A0 is the only name.
 2623    FM  (    0, 5,  0, 9,         "Intel Quark X1000 / D1000 / D2000 / C1000 (Lakemont)");
 2624    F   (    0, 5,                "Intel Pentium (unknown model)");
 2625    FM  (    0, 6,  0, 0,         "Intel Pentium Pro A-step");
 2626    // Intel docs (242689).
 2627    FMS (    0, 6,  0, 1,  1,     "Intel Pentium Pro (B0)");
 2628    FMS (    0, 6,  0, 1,  2,     "Intel Pentium Pro (C0)");
 2629    FMS (    0, 6,  0, 1,  6,     "Intel Pentium Pro (sA0)");
 2630    FMS (    0, 6,  0, 1,  7,     "Intel Pentium Pro (sA1), .35um");
 2631    FMS (    0, 6,  0, 1,  9,     "Intel Pentium Pro (sB1), .35um");
 2632    FM  (    0, 6,  0, 1,         "Intel Pentium Pro");
 2633    // Intel docs (243337)
 2634    TFM (1,  0, 6,  0, 3,         "Intel Pentium II OverDrive");
 2635    FMS (    0, 6,  0, 3,  3,     "Intel Pentium II (Klamath C0)");
 2636    FMS (    0, 6,  0, 3,  4,     "Intel Pentium II (Klamath C1)");
 2637    FM  (    0, 6,  0, 3,         "Intel Pentium II (Klamath)");
 2638    FM  (    0, 6,  0, 4,         "Intel Pentium P55CT OverDrive (Deschutes)");
 2639    // Intel docs (243337, 243748, 243776, 243887).
 2640    FMSQ(    0, 6,  0, 5,  0, xD, "Intel Pentium II Xeon (Deschutes A0)");
 2641    FMSQ(    0, 6,  0, 5,  0, mD, "Intel Mobile Pentium II (Deschutes A0)");
 2642    FMSQ(    0, 6,  0, 5,  0, cD, "Intel Celeron (Deschutes A0)");
 2643    FMS (    0, 6,  0, 5,  0,     "Intel Pentium II (unknown type) (Deschutes A0)");
 2644    FMSQ(    0, 6,  0, 5,  1, xD, "Intel Pentium II Xeon (Deschutes A1)");
 2645    FMSQ(    0, 6,  0, 5,  1, cD, "Intel Celeron (Deschutes A1)");
 2646    FMS (    0, 6,  0, 5,  1,     "Intel Pentium II (unknown type) (Deschutes A1)");
 2647    FMSQ(    0, 6,  0, 5,  2, xD, "Intel Pentium II Xeon (Deschutes B0)");
 2648    FMSQ(    0, 6,  0, 5,  2, mD, "Intel Mobile Pentium II (Deschutes B0)");
 2649    FMSQ(    0, 6,  0, 5,  2, cD, "Intel Celeron (Deschutes B0)");
 2650    FMS (    0, 6,  0, 5,  2,     "Intel Pentium II (unknown type) (Deschutes B0)");
 2651    FMSQ(    0, 6,  0, 5,  3, xD, "Intel Pentium II Xeon (Deschutes B1)");
 2652    FMSQ(    0, 6,  0, 5,  3, cD, "Intel Celeron (Deschutes B1)");
 2653    FMS (    0, 6,  0, 5,  3,     "Intel Pentium II (unknown type) (Deschutes B1)");
 2654    FMQ (    0, 6,  0, 5,     xD, "Intel Pentium II Xeon (Deschutes)");
 2655    FMQ (    0, 6,  0, 5,     mD, "Intel Mobile Pentium II (Deschutes)");
 2656    FMQ (    0, 6,  0, 5,     cD, "Intel Celeron (Deschutes)");
 2657    FM  (    0, 6,  0, 5,         "Intel Pentium II (unknown type) (Deschutes)");
 2658    // Intel docs (243748, 243887, 244444).
 2659    FMSQ(    0, 6,  0, 6,  0, dP, "Intel Pentium II (Mendocino A0)");
 2660    FMSQ(    0, 6,  0, 6,  0, dC, "Intel Celeron (Mendocino A0)");
 2661    FMS (    0, 6,  0, 6,  0,     "Intel Pentium II (unknown type) (Mendocino A0)");
 2662    FMSQ(    0, 6,  0, 6,  5, dC, "Intel Celeron (Mendocino B0)");
 2663    FMSQ(    0, 6,  0, 6,  5, dP, "Intel Pentium II (Mendocino B0)");
 2664    FMS (    0, 6,  0, 6,  5,     "Intel Pentium II (unknown type) (Mendocino B0)");
 2665    FMS (    0, 6,  0, 6, 10,     "Intel Mobile Pentium II (Mendocino A0)");
 2666    FM  (    0, 6,  0, 6,         "Intel Pentium II (Mendocino)");
 2667    // Intel docs (244453, 244460).
 2668    FMSQ(    0, 6,  0, 7,  2, pK, "Intel Pentium III (Katmai B0)");
 2669    FMSQ(    0, 6,  0, 7,  2, xK, "Intel Pentium III Xeon (Katmai B0)");
 2670    FMS (    0, 6,  0, 7,  2,     "Intel Pentium III (unknown type) (Katmai B0)");
 2671    FMSQ(    0, 6,  0, 7,  3, pK, "Intel Pentium III (Katmai C0)");
 2672    FMSQ(    0, 6,  0, 7,  3, xK, "Intel Pentium III Xeon (Katmai C0)");
 2673    FMS (    0, 6,  0, 7,  3,     "Intel Pentium III (unknown type) (Katmai C0)");
 2674    FMQ (    0, 6,  0, 7,     pK, "Intel Pentium III (Katmai)");
 2675    FMQ (    0, 6,  0, 7,     xK, "Intel Pentium III Xeon (Katmai)");
 2676    FM  (    0, 6,  0, 7,         "Intel Pentium III (unknown type) (Katmai)");
 2677    // Intel docs (243748, 244453, 244460, 245306, 245421).
 2678    FMSQ(    0, 6,  0, 8,  1, sX, "Intel Pentium III Xeon (Coppermine A2)");
 2679    FMSQ(    0, 6,  0, 8,  1, MC, "Intel Mobile Celeron (Coppermine A2)");
 2680    FMSQ(    0, 6,  0, 8,  1, dC, "Intel Celeron (Coppermine A2)");
 2681    FMSQ(    0, 6,  0, 8,  1, MP, "Intel Mobile Pentium III (Coppermine A2)");
 2682    FMSQ(    0, 6,  0, 8,  1, dP, "Intel Pentium III (Coppermine A2)");
 2683    FMS (    0, 6,  0, 8,  1,     "Intel Pentium III (unknown type) (Coppermine A2)");
 2684    FMSQ(    0, 6,  0, 8,  3, sX, "Intel Pentium III Xeon (Coppermine B0)");
 2685    FMSQ(    0, 6,  0, 8,  3, MC, "Intel Mobile Celeron (Coppermine B0)");
 2686    FMSQ(    0, 6,  0, 8,  3, dC, "Intel Celeron (Coppermine B0)");
 2687    FMSQ(    0, 6,  0, 8,  3, MP, "Intel Mobile Pentium III (Coppermine B0)");
 2688    FMSQ(    0, 6,  0, 8,  3, dP, "Intel Pentium III (Coppermine B0)");
 2689    FMS (    0, 6,  0, 8,  3,     "Intel Pentium III (unknown type) (Coppermine B0)");
 2690    FMSQ(    0, 6,  0, 8,  6, sX, "Intel Pentium III Xeon (Coppermine C0)");
 2691    FMSQ(    0, 6,  0, 8,  6, MC, "Intel Mobile Celeron (Coppermine C0)");
 2692    FMSQ(    0, 6,  0, 8,  6, dC, "Intel Celeron (Coppermine C0)");
 2693    FMSQ(    0, 6,  0, 8,  6, MP, "Intel Mobile Pentium III (Coppermine C0)");
 2694    FMSQ(    0, 6,  0, 8,  6, dP, "Intel Pentium III (Coppermine C0)");
 2695    FMS (    0, 6,  0, 8,  6,     "Intel Pentium III (unknown type) (Coppermine C0)");
 2696    FMSQ(    0, 6,  0, 8, 10, sX, "Intel Pentium III Xeon (Coppermine D0)");
 2697    FMSQ(    0, 6,  0, 8, 10, MC, "Intel Mobile Celeron (Coppermine D0)");
 2698    FMSQ(    0, 6,  0, 8, 10, dC, "Intel Celeron (Coppermine D0)");
 2699    FMSQ(    0, 6,  0, 8, 10, MP, "Intel Mobile Pentium III (Coppermine D0)");
 2700    FMSQ(    0, 6,  0, 8, 10, dP, "Intel Pentium III (Coppermine D0)");
 2701    FMS (    0, 6,  0, 8, 10,     "Intel Pentium III (unknown type) (Coppermine D0)");
 2702    FMQ (    0, 6,  0, 8,     sX, "Intel Pentium III Xeon (Coppermine)");
 2703    FMQ (    0, 6,  0, 8,     MC, "Intel Mobile Celeron (Coppermine)");
 2704    FMQ (    0, 6,  0, 8,     dC, "Intel Celeron (Coppermine)");
 2705    FMQ (    0, 6,  0, 8,     MP, "Intel Mobile Pentium III (Coppermine)");
 2706    FMQ (    0, 6,  0, 8,     dP, "Intel Pentium III (Coppermine)");
 2707    FM  (    0, 6,  0, 8,         "Intel Pentium III (unknown type) (Coppermine)");
 2708    // Intel docs (252665, 300303).
 2709    FMSQ(    0, 6,  0, 9,  5, dC, "Intel Celeron M (Banias B1)");
 2710    FMSQ(    0, 6,  0, 9,  5, dP, "Intel Pentium M (Banias B1)");
 2711    FMS (    0, 6,  0, 9,  5,     "Intel Pentium M (unknown type) (Banias B1)");
 2712    FMQ (    0, 6,  0, 9,     dC, "Intel Celeron M (Banias)");
 2713    FMQ (    0, 6,  0, 9,     dP, "Intel Pentium M (Banias)");
 2714    FM  (    0, 6,  0, 9,         "Intel Pentium M (unknown type) (Banias)");
 2715    // Intel docs (244460).
 2716    FMS (    0, 6,  0,10,  0,     "Intel Pentium III Xeon (Cascades A0)");
 2717    FMS (    0, 6,  0,10,  1,     "Intel Pentium III Xeon (Cascades A1)");
 2718    FMS (    0, 6,  0,10,  4,     "Intel Pentium III Xeon (Cascades B0)");
 2719    FM  (    0, 6,  0,10,         "Intel Pentium III Xeon (Cascades)");
 2720    // Intel docs (243748, 244453, 245306, 245421).
 2721    FMSQ(    0, 6,  0,11,  1, dC, "Intel Celeron (Tualatin A1)");
 2722    FMSQ(    0, 6,  0,11,  1, MC, "Intel Mobile Celeron (Tualatin A1)");
 2723    FMSQ(    0, 6,  0,11,  1, dP, "Intel Pentium III (Tualatin A1)");
 2724    FMS (    0, 6,  0,11,  1,     "Intel Pentium III (unknown type) (Tualatin A1)");
 2725    FMSQ(    0, 6,  0,11,  4, dC, "Intel Celeron (Tualatin B1)");
 2726    FMSQ(    0, 6,  0,11,  4, MC, "Intel Mobile Celeron (Tualatin B1)");
 2727    FMSQ(    0, 6,  0,11,  4, dP, "Intel Pentium III (Tualatin B1)");
 2728    FMS (    0, 6,  0,11,  4,     "Intel Pentium III (unknown type) (Tualatin B1)");
 2729    FMQ (    0, 6,  0,11,     dC, "Intel Celeron (Tualatin)");
 2730    FMQ (    0, 6,  0,11,     MC, "Intel Mobile Celeron (Tualatin)");
 2731    FMQ (    0, 6,  0,11,     dP, "Intel Pentium III (Tualatin)");
 2732    FM  (    0, 6,  0,11,         "Intel Pentium III (unknown type) (Tualatin)");
 2733    // Intel docs (300303, 302209).
 2734    FMSQ(    0, 6,  0,13,  6, dC, "Intel Celeron M (Dothan B1), 90nm");
 2735    FMSQ(    0, 6,  0,13,  6, dP, "Intel Pentium M (Dothan B1), 90nm");
 2736    FMS (    0, 6,  0,13,  6,     "Intel Pentium M (unknown type) (Dothan B1), 90nm");
 2737    FMSQ(    0, 6,  0,13,  8, dC, "Intel Celeron M (Dothan C0), 90nm/65nm");
 2738    FMSQ(    0, 6,  0,13,  8, MP, "Intel Processor A100/A110 (Stealey C0) / Pentium M (Crofton C0), 90nm");
 2739    FMSQ(    0, 6,  0,13,  8, dP, "Intel Pentium M (Dothan C0), 90nm");
 2740    FMS (    0, 6,  0,13,  8,     "Intel Pentium M (unknown type) (Dothan/Stealey/Crofton C0), 90nm/65nm");
 2741    FMQ (    0, 6,  0,13,     dC, "Intel Celeron M (Dothan)");
 2742    FMQ (    0, 6,  0,13,     MP, "Intel Processor A100/A110 (Stealey)");
 2743    FMQ (    0, 6,  0,13,     dP, "Intel Pentium M (Dothan)");
 2744    FM  (    0, 6,  0,13,         "Intel Pentium M (unknown type) (Dothan/Crofton)");
 2745    // Intel docs (300303, 309222, 311392, 316515).
 2746    FMSQ(    0, 6,  0,14,  8, sX, "Intel Xeon Processor LV (Sossaman C0)");
 2747    FMSQ(    0, 6,  0,14,  8, dC, "Intel Celeron (Yonah C0)");
 2748    FMSQ(    0, 6,  0,14,  8, DG, "Intel Core Duo (Yonah C0)");
 2749    FMSQ(    0, 6,  0,14,  8, dG, "Intel Core Solo (Yonah C0)");
 2750    FMS (    0, 6,  0,14,  8,     "Intel Core (unknown type) (Yonah/Sossaman C0)");
 2751    FMSQ(    0, 6,  0,14, 12, sX, "Intel Xeon Processor LV (Sossaman D0)");
 2752    FMSQ(    0, 6,  0,14, 12, dC, "Intel Celeron M (Yonah D0)");
 2753    FMSQ(    0, 6,  0,14, 12, MP, "Intel Pentium Dual-Core Mobile T2000 (Yonah D0)");
 2754    FMSQ(    0, 6,  0,14, 12, DG, "Intel Core Duo (Yonah D0)");
 2755    FMSQ(    0, 6,  0,14, 12, dG, "Intel Core Solo (Yonah D0)");
 2756    FMS (    0, 6,  0,14, 12,     "Intel Core (unknown type) (Yonah/Sossaman D0)");
 2757    FMS (    0, 6,  0,14, 13,     "Intel Pentium Dual-Core Mobile T2000 (Yonah M0)");
 2758    FMQ (    0, 6,  0,14,     sX, "Intel Xeon Processor LV (Sossaman)");
 2759    FMQ (    0, 6,  0,14,     dC, "Intel Celeron (Yonah)");
 2760    FMQ (    0, 6,  0,14,     MP, "Intel Pentium Dual-Core Mobile (Yonah)");
 2761    FMQ (    0, 6,  0,14,     DG, "Intel Core Duo (Yonah)");
 2762    FMQ (    0, 6,  0,14,     dG, "Intel Core Solo (Yonah)");
 2763    FM  (    0, 6,  0,14,         "Intel Core (unknown type) (Yonah/Sossaman)");
 2764    // Intel docs (313279, 313356, 314079, 314916, 315338, 315593, 316134,
 2765    // 316515, 316982, 317667, 318081, 318925, 319735).
 2766    FMSQ(    0, 6,  0,15,  2, sX, "Intel Dual-Core Xeon Processor 3000 (Conroe L2)");
 2767    FMSQ(    0, 6,  0,15,  2, Mc, "Intel Core Duo Mobile (Merom L2)");
 2768    FMSQ(    0, 6,  0,15,  2, dc, "Intel Core Duo (Conroe L2)");
 2769    FMSQ(    0, 6,  0,15,  2, dP, "Intel Pentium Dual-Core Desktop Processor E2000 (Allendale L2)");
 2770    FMS (    0, 6,  0,15,  2,     "Intel Core (unknown type) (Conroe/Merom/Allendale L2)");
 2771    FMS (    0, 6,  0,15,  4,     "Intel Core 2 Duo (Conroe B0) / Xeon Processor 5100 (Woodcrest B0) (pre-production)");
 2772    FMSQ(    0, 6,  0,15,  5, QW, "Intel Dual-Core Xeon Processor 5100 (Woodcrest B1) (pre-production)");
 2773    FMSQ(    0, 6,  0,15,  5, XE, "Intel Core 2 Extreme Processor (Conroe B1)");
 2774    FMSQ(    0, 6,  0,15,  5, dL, "Intel Core 2 Duo (Allendale B1)");
 2775    FMSQ(    0, 6,  0,15,  5, dc, "Intel Core 2 Duo (Conroe B1)");
 2776    FMS (    0, 6,  0,15,  5,     "Intel Core 2 (unknown type) (Conroe/Allendale B1)");
 2777    FMSQ(    0, 6,  0,15,  6, Xc, "Intel Core 2 Extreme Processor (Conroe B2)");
 2778    FMSQ(    0, 6,  0,15,  6, Mc, "Intel Core 2 Duo Mobile (Merom B2)");
 2779    FMSQ(    0, 6,  0,15,  6, dL, "Intel Core 2 Duo (Allendale B2)");
 2780    FMSQ(    0, 6,  0,15,  6, dc, "Intel Core 2 Duo (Conroe B2)");
 2781    FMSQ(    0, 6,  0,15,  6, dC, "Intel Celeron M (Conroe B2)");
 2782    FMSQ(    0, 6,  0,15,  6, sX, "Intel Dual-Core Xeon Processor 3000 (Conroe B2) / Dual-Core Xeon Processor 5100 (Woodcrest B2)");
 2783    FMS (    0, 6,  0,15,  6,     "Intel Core 2 (unknown type) (Conroe/Allendale/Woodcrest B2)");
 2784    FMSQ(    0, 6,  0,15,  7, sX, "Intel Quad-Core Xeon Processor 3200 (Kentsfield B3) / Quad-Core Xeon Processor 5300 (Clovertown B3)");
 2785    FMSQ(    0, 6,  0,15,  7, Xc, "Intel Core 2 Extreme Quad-Core Processor QX6xx0 (Kentsfield B3)");
 2786    FMS (    0, 6,  0,15,  7,     "Intel Core 2 (unknown type) (Kentsfield/Clovertown B3)");
 2787    FMSQ(    0, 6,  0,15, 10, Mc, "Intel Core 2 Duo Mobile (Merom E1)");
 2788    FMSQ(    0, 6,  0,15, 10, dC, "Intel Celeron Processor 500 (Merom E1)");
 2789    FMS (    0, 6,  0,15, 10,     "Intel Core 2 (unknown type) (Merom E1)");
 2790    FMSQ(    0, 6,  0,15, 11, sQ, "Intel Quad-Core Xeon Processor 5300 (Clovertown G0)");
 2791    FMSQ(    0, 6,  0,15, 11, sX, "Intel Xeon Processor 3000 (Conroe G0) / Xeon Processor 3200 (Kentsfield G0) / Xeon Processor 7200/7300 (Tigerton G0)");
 2792    FMSQ(    0, 6,  0,15, 11, Xc, "Intel Core 2 Extreme Quad-Core Processor QX6xx0 (Kentsfield G0)");
 2793    FMSQ(    0, 6,  0,15, 11, Mc, "Intel Core 2 Duo Mobile (Merom G2)");
 2794    FMSQ(    0, 6,  0,15, 11, Qc, "Intel Core 2 Quad (Conroe G0)");
 2795    FMSQ(    0, 6,  0,15, 11, dc, "Intel Core 2 Duo (Conroe G0)");
 2796    FMS (    0, 6,  0,15, 11,     "Intel Core 2 (unknown type) (Merom/Conroe/Kentsfield/Clovertown/Tigerton G0)");
 2797    FMSQ(    0, 6,  0,15, 13, Mc, "Intel Core 2 Duo Mobile (Merom M1) / Celeron Processor 500 (Merom E1)");
 2798    FMSQ(    0, 6,  0,15, 13, Qc, "Intel Core 2 Quad (Conroe M0)");
 2799    FMSQ(    0, 6,  0,15, 13, dc, "Intel Core 2 Duo (Conroe M0)");
 2800    FMSQ(    0, 6,  0,15, 13, dP, "Intel Pentium Dual-Core Desktop Processor E2000 (Allendale M0)");
 2801    FMSQ(    0, 6,  0,15, 13, dC, "Intel Celeron Dual-Core E1000 (Allendale M0) / Celeron Dual-Core T1000 (Merom M0)");
 2802    FMS (    0, 6,  0,15, 13,     "Intel Core 2 (unknown type) (Merom/Conroe/Allendale M0 / Merom E1)");
 2803    FMQ (    0, 6,  0,15,     sQ, "Intel Quad-Core Xeon (Woodcrest)");
 2804    FMQ (    0, 6,  0,15,     sX, "Intel Dual-Core Xeon (Conroe / Woodcrest) / Quad-Core Xeon (Kentsfield / Clovertown) / Xeon (Tigerton G0)");
 2805    FMQ (    0, 6,  0,15,     Xc, "Intel Core 2 Extreme Processor (Conroe) / Core 2 Extreme Quad-Core (Kentsfield)");
 2806    FMQ (    0, 6,  0,15,     Mc, "Intel Core Duo Mobile / Core 2 Duo Mobile (Merom) / Celeron (Merom)");
 2807    FMQ (    0, 6,  0,15,     Qc, "Intel Core 2 Quad (Conroe)");
 2808    FMQ (    0, 6,  0,15,     dc, "Intel Core Duo / Core 2 Duo (Conroe)");
 2809    FMQ (    0, 6,  0,15,     dP, "Intel Pentium Dual-Core (Allendale)");
 2810    FMQ (    0, 6,  0,15,     dC, "Intel Celeron M (Conroe) / Celeron (Merom) / Celeron Dual-Core (Allendale)");
 2811    FM  (    0, 6,  0,15,         "Intel Core 2 (unknown type) (Merom/Conroe/Allendale/Kentsfield/Allendale/Clovertown/Woodcrest/Tigerton)");
 2812    // Intel docs (320257).
 2813    FMS (    0, 6,  1, 5,  0,     "Intel EP80579 (Tolapai B0)");
 2814    // Intel docs (314079, 316964, 317667, 318547).
 2815    FMSQ(    0, 6,  1, 6,  1, MC, "Intel Celeron Processor 200/400/500 (Conroe-L/Merom-L A1)");
 2816    FMSQ(    0, 6,  1, 6,  1, dC, "Intel Celeron M (Merom-L A1)");
 2817    FMSQ(    0, 6,  1, 6,  1, Mc, "Intel Core 2 Duo Mobile (Merom A1)");
 2818    FMS (    0, 6,  1, 6,  1,     "Intel Core 2 (unknown type) (Merom/Conroe A1)");
 2819    FMQ (    0, 6,  1, 6,     MC, "Intel Celeron Processor 200/400/500 (Conroe-L/Merom-L)");
 2820    FMQ (    0, 6,  1, 6,     dC, "Intel Celeron M (Merom-L)");
 2821    FMQ (    0, 6,  1, 6,     Mc, "Intel Core 2 Duo Mobile (Merom)");
 2822    FM  (    0, 6,  1, 6,         "Intel Core 2 (unknown type) (Merom/Conroe)");
 2823    // Intel docs (318585, 318586, 318727, 318733, 318915, 319006, 319007,
 2824    // 319129, 320121, 320468, 320469, 322568).
 2825    FMSQ(    0, 6,  1, 7,  6, sQ, "Intel Xeon Processor 3300 (Yorkfield C0) / Xeon Processor 5200 (Wolfdale C0) / Xeon Processor 5400 (Harpertown C0)");
 2826    FMSQ(    0, 6,  1, 7,  6, sX, "Intel Xeon Processor 3100 (Wolfdale C0) / Xeon Processor 5200 (Wolfdale C0) / Xeon Processor 5400 (Harpertown C0)");
 2827    FMSQ(    0, 6,  1, 7,  6, Xc, "Intel Core 2 Extreme QX9000 (Yorkfield C0)");
 2828    FMSQ(    0, 6,  1, 7,  6, Me, "Intel Mobile Core 2 Duo (Penryn C0)");
 2829    FMSQ(    0, 6,  1, 7,  6, Mc, "Intel Mobile Core 2 Duo (Penryn M0)");
 2830    FMSQ(    0, 6,  1, 7,  6, de, "Intel Core 2 Duo (Wolfdale C0)");
 2831    FMSQ(    0, 6,  1, 7,  6, dc, "Intel Core 2 Duo (Wolfdale M0)");
 2832    FMSQ(    0, 6,  1, 7,  6, dP, "Intel Pentium Dual-Core Processor E5000 (Wolfdale M0)");
 2833    FMS (    0, 6,  1, 7,  6,     "Intel Core 2 (unknown type) (Penryn/Wolfdale/Yorkfield/Harpertown C0/M0)");
 2834    FMSQ(    0, 6,  1, 7,  7, sQ, "Intel Xeon Processor 3300 (Yorkfield C1)");
 2835    FMSQ(    0, 6,  1, 7,  7, Xc, "Intel Core 2 Extreme QX9000 (Yorkfield C1)");
 2836    FMSQ(    0, 6,  1, 7,  7, Qe, "Intel Core 2 Quad-Core Q9000 (Yorkfield C1)");
 2837    FMSQ(    0, 6,  1, 7,  7, Qc, "Intel Core 2 Quad-Core Q9000 (Yorkfield M1)");
 2838    FMS (    0, 6,  1, 7,  7,     "Intel Core 2 (unknown type) (Penryn/Wolfdale/Yorkfield/Harpertown C1/M1)");
 2839    FMSQ(    0, 6,  1, 7, 10, Me, "Intel Mobile Core 2 (Penryn E0)");
 2840    FMSQ(    0, 6,  1, 7, 10, Mc, "Intel Mobile Core 2 (Penryn R0)");
 2841    FMSQ(    0, 6,  1, 7, 10, Qe, "Intel Core 2 Quad-Core Q9000 (Yorkfield E0)");
 2842    FMSQ(    0, 6,  1, 7, 10, Qc, "Intel Core 2 Quad-Core Q9000 (Yorkfield R0)");
 2843    FMSQ(    0, 6,  1, 7, 10, de, "Intel Core 2 Duo (Wolfdale E0)");
 2844    FMSQ(    0, 6,  1, 7, 10, dc, "Intel Core 2 Duo (Wolfdale R0)");
 2845    FMSQ(    0, 6,  1, 7, 10, dP, "Intel Pentium Dual-Core Processor E5000/E6000 / Pentium T4000 (Wolfdale R0)");
 2846    FMSQ(    0, 6,  1, 7, 10, dC, "Intel Celeron E3000 / T3000 / 900 / SU2300 (Wolfdale R0)"); // T3000 & 900 names from MRG* 2018-03-06
 2847    FMSQ(    0, 6,  1, 7, 10, MC, "Intel Celeron M ULV 700 (Penryn R0)");
 2848    FMSQ(    0, 6,  1, 7, 10, se, "Intel Xeon Processor 3300 (Yorkfield E0)");
 2849    FMSQ(    0, 6,  1, 7, 10, sQ, "Intel Xeon Processor 3300 (Yorkfield R0)");
 2850    FMSQ(    0, 6,  1, 7, 10, sX, "Intel Xeon Processor 3100 (Wolfdale E0) / Xeon Processor 3300 (Yorkfield R0) / Xeon Processor 5200 (Wolfdale E0) / Xeon Processor 5400 (Harpertown E0)");
 2851    FMS (    0, 6,  1, 7, 10,     "Intel Core 2 (unknown type) (Penryn/Wolfdale/Yorkfield/Harpertown E0/R0)");
 2852    FMQ (    0, 6,  1, 7,     se, "Intel Xeon (Wolfdale / Yorkfield / Harpertown)");
 2853    FMQ (    0, 6,  1, 7,     sQ, "Intel Xeon (Wolfdale / Yorkfield / Harpertown)");
 2854    FMQ (    0, 6,  1, 7,     sX, "Intel Xeon (Wolfdale / Yorkfield / Harpertown)");
 2855    FMQ (    0, 6,  1, 7,     Mc, "Intel Mobile Core 2 (Penryn)");
 2856    FMQ (    0, 6,  1, 7,     Xc, "Intel Core 2 Extreme (Yorkfield)");
 2857    FMQ (    0, 6,  1, 7,     Qc, "Intel Core 2 Quad-Core (Yorkfield)");
 2858    FMQ (    0, 6,  1, 7,     dc, "Intel Core 2 Duo (Wolfdale)");
 2859    FMQ (    0, 6,  1, 7,     dC, "Intel Celeron (Wolfdale)");
 2860    FMQ (    0, 6,  1, 7,     MC, "Intel Celeron M ULV (Penryn)");
 2861    FMQ (    0, 6,  1, 7,     dP, "Intel Pentium (Wolfdale)");
 2862    FM  (    0, 6,  1, 7,         "Intel Core 2 (unknown type) (Penryn/Wolfdale/Yorkfield/Harpertown)");
 2863    // Intel docs (320836, 321324, 321333).
 2864    FMS (    0, 6,  1,10,  4,     "Intel Core i7-900 (Bloomfield C0)");
 2865    FMSQ(    0, 6,  1,10,  5, dc, "Intel Core i7-900 (Bloomfield D0)");
 2866    FMSQ(    0, 6,  1,10,  5, sX, "Intel Xeon Processor 3500 (Bloomfield D0) / Xeon Processor 5500 (Gainestown D0)");
 2867    FMS (    0, 6,  1,10,  5,     "Intel Core (unknown type) (Bloomfield/Gainestown D0)");
 2868    FMQ (    0, 6,  1,10,     dc, "Intel Core (Bloomfield)");
 2869    FMQ (    0, 6,  1,10,     sX, "Intel Xeon (Bloomfield / Gainestown)");
 2870    FM  (    0, 6,  1,10,         "Intel Core (unknown type) (Bloomfield / Gainestown)");
 2871    // Intel docs (319536, 319974, 320047, 320529, 322861, 322862, 322849,
 2872    // 324341).
 2873    FMS (    0, 6,  1,12,  1,     "Intel Atom N270 (Diamondville B0)");
 2874    FMS (    0, 6,  1,12,  2,     "Intel Atom 200/N200/300 (Diamondville C0) / Atom Z500 (Silverthorne C0)");
 2875    FMS (    0, 6,  1,12, 10,     "Intel Atom D400/N400 (Pineview A0) / Atom D500/N500 (Pineview B0)");
 2876    FM  (    0, 6,  1,12,         "Intel Atom (Diamondville / Silverthorne / Pineview)");
 2877    // Intel docs (320336).
 2878    FMS (    0, 6,  1,13,  1,     "Intel Xeon Processor 7400 (Dunnington A1)");
 2879    FM  (    0, 6,  1,13,         "Intel Xeon (unknown type) (Dunnington)");
 2880    // Intel docs (320767, 322166, 322373, 323105).
 2881    FMSQ(    0, 6,  1,14,  4, sX, "Intel Xeon Processor EC3500/EC5500 (Jasper Forest B0)"); // EC names from MRG* 2018-03-06
 2882    FMSQ(    0, 6,  1,14,  4, dC, "Intel Celeron P1053 (Jasper Forest B0)");
 2883    FMS (    0, 6,  1,14,  4,     "Intel Xeon (unknown type) (Jasper Forest B0)");
 2884    FMSQ(    0, 6,  1,14,  5, sX, "Intel Xeon Processor 3400 (Lynnfield B1)");
 2885    FMSQ(    0, 6,  1,14,  5, Mc, "Intel Core i7-700/800/900 Mobile (Clarksfield B1)");
 2886    FMSQ(    0, 6,  1,14,  5, dc, "Intel Core i*-700/800/900 (Lynnfield B1)"); // 900 from MRG* 2018-03-06
 2887    FMS (    0, 6,  1,14,  5,     "Intel Core (unknown type) (Lynnfield/Clarksfield B1)");
 2888    FMQ (    0, 6,  1,14,     sX, "Intel Xeon (Lynnfield) / Xeon (Jasper Forest)");
 2889    FMQ (    0, 6,  1,14,     dC, "Intel Celeron (Jasper Forest)");
 2890    FMQ (    0, 6,  1,14,     Mc, "Intel Core Mobile (Clarksfield)");
 2891    FMQ (    0, 6,  1,14,     dc, "Intel Core (Lynnfield)");
 2892    FM  (    0, 6,  1,14,         "Intel Core (unknown type) (Lynnfield/Clarksfield)");
 2893    FM  (    0, 6,  1,15,         "Intel (unknown model) (Havendale/Auburndale)");
 2894    // Intel docs (322814, 322911, 323179, 323847, 323056, 324456).
 2895    FMSQ(    0, 6,  2, 5,  2, sX, "Intel Xeon Processor L3406 (Clarkdale C2)");
 2896    FMSQ(    0, 6,  2, 5,  2, MC, "Intel Celeron Mobile P4500 (Arrandale C2)");
 2897    FMSQ(    0, 6,  2, 5,  2, MP, "Intel Pentium P6000 Mobile (Arrandale C2)");
 2898    FMSQ(    0, 6,  2, 5,  2, dP, "Intel Pentium G6900 / P4500 (Clarkdale C2)");
 2899    FMSQ(    0, 6,  2, 5,  2, Mc, "Intel Core i*-300/400/500/600 Mobile (Arrandale C2)");
 2900    FMSQ(    0, 6,  2, 5,  2, dc, "Intel Core i*-300/500/600 (Clarkdale C2)");
 2901    FMS (    0, 6,  2, 5,  2,     "Intel Core (unknown type) (Clarkdale/Arrandale C2)");
 2902    FMSQ(    0, 6,  2, 5,  5, MC, "Intel Celeron Mobile U3400 (Arrandale K0) / Celeron Mobile P4600 (Arrandale K0)");
 2903    FMSQ(    0, 6,  2, 5,  5, MP, "Intel Pentium U5000 Mobile (Arrandale K0)");
 2904    FMSQ(    0, 6,  2, 5,  5, dP, "Intel Pentium P4500 / U3400 / G6900 (Clarkdale K0)"); // G6900 only from MRG* 2018-03-06
 2905    FMSQ(    0, 6,  2, 5,  5, dc, "Intel Core i*-300/400/500/600 (Clarkdale K0)");
 2906    FMS (    0, 6,  2, 5,  5,     "Intel Core (unknown type) (Clarkdale/Arrandale K0)");
 2907    FMQ (    0, 6,  2, 5,     sX, "Intel Xeon Processor L3406 (Clarkdale)");
 2908    FMQ (    0, 6,  2, 5,     MC, "Intel Celeron Mobile (Arrandale)");
 2909    FMQ (    0, 6,  2, 5,     MP, "Intel Pentium Mobile (Arrandale)");
 2910    FMQ (    0, 6,  2, 5,     dP, "Intel Pentium (Clarkdale)");
 2911    FMQ (    0, 6,  2, 5,     Mc, "Intel Core Mobile (Arrandale)");
 2912    FMQ (    0, 6,  2, 5,     dc, "Intel Core (Clarkdale)");
 2913    FM  (    0, 6,  2, 5,         "Intel Core (unknown type) (Clarkdale/Arrandale)");
 2914    // Intel docs (324209, 325307, 325309, 325630).
 2915    FMS (    0, 6,  2, 6,  1,     "Intel Atom Z600 (Lincroft C0) / Atom E600 (Tunnel Creek B0/B1)");
 2916    FM  (    0, 6,  2, 6,         "Intel Atom Z600 (Lincroft) / Atom E600 (Tunnel Creek B0/B1)");
 2917    FM  (    0, 6,  2, 7,         "Intel Atom Z2000 (Medfield)"); // no spec update, only instlatx64 example (stepping 1)
 2918    // Intel docs (327335) omit stepping numbers, but (324643, 324827, 324972)
 2919    // provide some.  An instlatx64 stepping 6 example has been spoted, but it
 2920    // isn't known which stepping name that is.
 2921    FMSQ(    0, 6,  2,10,  7, Xc, "Intel Mobile Core i7 Extreme (Sandy Bridge D2/J1/Q0)");
 2922    FMSQ(    0, 6,  2,10,  7, Mc, "Intel Mobile Core i*-2000 (Sandy Bridge D2/J1/Q0)");
 2923    FMSQ(    0, 6,  2,10,  7, dc, "Intel Core i*-2000 (Sandy Bridge D2/J1/Q0)");
 2924    FMSQ(    0, 6,  2,10,  7, MC, "Intel Celeron G400/G500/700/800/B800 (Sandy Bridge J1/Q0)");
 2925    FMSQ(    0, 6,  2,10,  7, sX, "Intel Xeon E3-1100 / E3-1200 v1 (Sandy Bridge D2/J1/Q0)");
 2926    FMSQ(    0, 6,  2,10,  7, dP, "Intel Pentium G500/G600/G800 / Pentium 900 (Sandy Bridge Q0)");
 2927    FMS (    0, 6,  2,10,  7,     "Intel Core (unknown type) (Sandy Bridge D2/J1/Q0)");
 2928    FMQ (    0, 6,  2,10,     Xc, "Intel Mobile Core i7 Extreme (Sandy Bridge)");
 2929    FMQ (    0, 6,  2,10,     Mc, "Intel Mobile Core i*-2000 (Sandy Bridge)");
 2930    FMQ (    0, 6,  2,10,     dc, "Intel Core i*-2000 (Sandy Bridge)");
 2931    FMQ (    0, 6,  2,10,     MC, "Intel Celeron G400/G500/700/800/B800 (Sandy Bridge)");
 2932    FMQ (    0, 6,  2,10,     sX, "Intel Xeon E3-1100 / E3-1200 v1 (Sandy Bridge)");
 2933    FMQ (    0, 6,  2,10,     dP, "Intel Pentium G500/G600/G800 / Pentium 900 (Sandy Bridge)");
 2934    FM  (    0, 6,  2,10,         "Intel Core (unknown type) (Sandy Bridge)");
 2935    // Intel docs (323254: i7-900, 323338: Xeon 3600, 323372: Xeon 5600).
 2936    // https://en.wikipedia.org/wiki/Westmere_(microarchitecture) provided
 2937    // A0 & B0 stepping values.
 2938    FMSQ(    0, 6,  2,12,  0, dc, "Intel Core i7-900 / Core i7-980X (Gulftown A0)");
 2939    FMSQ(    0, 6,  2,12,  0, sX, "Intel Xeon Processor 3600 / 5600 (Westmere-EP A0)");
 2940    FMS (    0, 6,  2,12,  0,     "Intel Core (unknown type) (Gulftown/Westmere-EP A0)");
 2941    FMSQ(    0, 6,  2,12,  1, dc, "Intel Core i7-900 / Core i7-980X (Gulftown B0)");
 2942    FMSQ(    0, 6,  2,12,  1, sX, "Intel Xeon Processor 3600 / 5600 (Westmere-EP B0)");
 2943    FMS (    0, 6,  2,12,  1,     "Intel Core (unknown type) (Gulftown/Westmere-EP B0)");
 2944    FMSQ(    0, 6,  2,12,  2, dc, "Intel Core i7-900 / Core i7-980X (Gulftown B1)");
 2945    FMSQ(    0, 6,  2,12,  2, sX, "Intel Xeon Processor 3600 / 5600 (Westmere-EP B1)");
 2946    FMS (    0, 6,  2,12,  2,     "Intel Core (unknown type) (Gulftown/Westmere-EP B1)");
 2947    FMQ (    0, 6,  2,12,     dc, "Intel Core (unknown type) (Gulftown)");
 2948    FMQ (    0, 6,  2,12,     sX, "Intel Xeon (unknown type) (Westmere-EP)");
 2949    FM  (    0, 6,  2,12,         "Intel (unknown type) (Gulftown/Westmere-EP)");
 2950    // Intel docs (326198, 326510).
 2951    FMSQ(    0, 6,  2,13,  6, sX, "Intel Xeon E5-1600/2600 (Sandy Bridge-E C1/M0)");
 2952    FMSQ(    0, 6,  2,13,  6, dc, "Intel Core i7-3800/3900 (Sandy Bridge-E C1)");
 2953    FMS (    0, 6,  2,13,  6,     "Intel Core (unknown type) (Sandy Bridge-E C1)");
 2954    FMSQ(    0, 6,  2,13,  7, sX, "Intel Xeon E5-1600/2600/4600 (Sandy Bridge-E C2/M1)");
 2955    FMSQ(    0, 6,  2,13,  7, dc, "Intel Core i7-3800/3900 (Sandy Bridge-E C2)");
 2956    FMSQ(    0, 6,  2,13,  7, dP, "Intel Pentium 1405 (Sandy Bridge-E C1)"); // MRG* 2018-03-06
 2957    FMS (    0, 6,  2,13,  7,     "Intel Core (unknown type) (Sandy Bridge-E C2/M1)");
 2958    FMQ (    0, 6,  2,13,     sX, "Intel Xeon E5-1600/2600 (Sandy Bridge-E)");
 2959    FMQ (    0, 6,  2,13,     dc, "Intel Core i7-3800/3900 (Sandy Bridge-E)");
 2960    FMQ (    0, 6,  2,13,     dP, "Intel Pentium 1405 (Sandy Bridge-E)"); // MRG* 2018-03-06
 2961    FM  (    0, 6,  2,13,         "Intel Core (unknown type) (Sandy Bridge-E)");
 2962    // Intel docs (323344) are inconsistent.  Using Table 2 information.
 2963    // instlatx64 samples have steppings 4 & 5, but no idea which stepping names
 2964    // those are.
 2965    FMS (    0, 6,  2,14,  6,     "Intel Xeon Processor 6500 / 7500 (Beckton D0)");
 2966    FM  (    0, 6,  2,14,         "Intel Xeon Processor 6500 / 7500 (Beckton)");
 2967    // Intel docs (325122).
 2968    FMS (    0, 6,  2,15,  2,     "Intel Xeon E7-8800 / Xeon E7-4800 / Xeon E7-2800 (Westmere-EX A2)");
 2969    FM  (    0, 6,  2,15,         "Intel Xeon (unknown type) (Westmere-EX)");
 2970    // Intel docs (332067) omit stepping numbers for D1, but (328105) provide
 2971    // some.
 2972    FMS (    0, 6,  3, 5,  1,     "Intel Atom Z2760 (Clover Trail C0) / Z8000 (Cherry Trail C0)");
 2973    FM  (    0, 6,  3, 5,         "Intel Atom Z2760 (Clover Trail) / Z8000 (Cherry Trail)");
 2974    // Intel docs (326140) for Cedarview
 2975    // Intel docs (328198) do not provide any FMS for Centerton, but an example
 2976    // from jhladky@redhat.com does.
 2977    // instlatx64 has example with stepping 9, but no idea what stepping name
 2978    // that is.
 2979    FMS (    0, 6,  3, 6,  1,     "Intel Atom D2000/N2000 (Cedarview B1/B2/B3) / S1200 (Centerton B1)");
 2980    FM  (    0, 6,  3, 6,         "Intel Atom D2000/N2000 (Cedarview) / S1200 (Centerton)");
 2981    // Intel docs (329475, 329671, 329901, 600827).
 2982    FMS (    0, 6,  3, 7,  1,     "Intel Atom Z3000 (Bay Trail-T A0)");
 2983    FMSQ(    0, 6,  3, 7,  2, dC, "Intel Celeron N2800 / N2900 (Bay Trail-M B0/B1)");
 2984    FMSQ(    0, 6,  3, 7,  2, dP, "Intel Pentium N3500 / J2800 / J2900 (Bay Trail-M B0/B1)");
 2985    FMS (    0, 6,  3, 7,  2,     "Intel Atom (unknown type) (Bay Trail-M B0/B1)");
 2986    FMSQ(    0, 6,  3, 7,  3, dC, "Intel Celeron N1700 / N1800 / N2800 / N2900 / J1700 / J1800 / J1900 (Bay Trail-M B2/B3)");
 2987    FMSQ(    0, 6,  3, 7,  3, dP, "Intel Pentium N3500 / J2800 / J2900 (Bay Trail-M B2/B3) / Atom E3800 (Bay Trail-I B3)");
 2988    FMSQ(    0, 6,  3, 7,  3, da, "Intel Atom E3800 / Z3700 (Bay Trail-I B3)"); // Z3700 only from MRG* 2019-08-31
 2989    FMS (    0, 6,  3, 7,  3,     "Intel Atom (unknown type) (Bay Trail B2/B3)");
 2990    FMSQ(    0, 6,  3, 7,  4, dC, "Intel Celeron N2800 / N2900 (Bay Trail-M C0)");
 2991    FMSQ(    0, 6,  3, 7,  4, dP, "Intel Pentium N3500 / J2800 / J2900 (Bay Trail-M C0)");
 2992    FMS (    0, 6,  3, 7,  4,     "Intel Atom (unknown type) (Bay Trail-M C0 / Bay Trail-T B2/B3)");
 2993    FMSQ(    0, 6,  3, 7,  8, da, "Intel Atom Z3700 (Bay Trail)"); // only MRG* 2019-08-31 (unknown stepping name)
 2994    FMSQ(    0, 6,  3, 7,  8, dC, "Intel Celeron N2800 / N2900 (Bay Trail)"); // only MRG* 2019-08-31 (unknown stepping name)
 2995    FMSQ(    0, 6,  3, 7,  8, dP, "Intel Pentium N3500 (Bay Trail)"); // only MRG* 2019-08-31 (unknown stepping name)
 2996    FMS (    0, 6,  3, 7,  8,     "Intel Atom (unknown type) (Bay Trail)"); // only MRG* 2019-08-31 (unknown stepping name)
 2997    FMSQ(    0, 6,  3, 7,  9, da, "Intel Atom E3800 (Bay Trail-I D0)");
 2998    FMSQ(    0, 6,  3, 7,  9, dC, "Intel Celeron N2800 / N2900 (Bay Trail-M/D D0/D1)"); // only MRG* 2018-03-06
 2999    FMSQ(    0, 6,  3, 7,  9, dP, "Intel Pentium J1800 / J1900 (Bay Trail-M/D D0/D1)"); // only MRG* 2018-03-06
 3000    FMS (    0, 6,  3, 7,  9,     "Intel Atom (unknown type) (Bay Trail D0)");
 3001    FM  (    0, 6,  3, 7,         "Intel Atom (unknown type) (Bay Trail-M / Bay Trail-T / Bay Trail-I)");
 3002    // Intel docs (326766, 326770, 326774, 329376).
 3003    // How to differentiate Gladden from Ivy Bridge here?
 3004    FMSQ(    0, 6,  3,10,  9, Mc, "Intel Mobile Core i*-3000 (Ivy Bridge E1/L1) / Pentium 900/1000/2000/2100 (P0)");
 3005    FMSQ(    0, 6,  3,10,  9, dc, "Intel Core i*-3000 (Ivy Bridge E1/N0/L1)");
 3006    FMSQ(    0, 6,  3,10,  9, sX, "Intel Xeon E3-1100 v2 / E3-1200 v2 (Ivy Bridge E1/N0/L1)");
 3007    FMSQ(    0, 6,  3,10,  9, dC, "Intel Celeron 1000 / G1600 (Ivy Bridge P0)"); // only MRG 2019-08-31
 3008    FMSQ(    0, 6,  3,10,  9, dP, "Intel Pentium G1600/G2000/G2100 / Pentium B900C (Ivy Bridge P0)");
 3009    FMS (    0, 6,  3,10,  9,     "Intel Core (unknown type) (Ivy Bridge E1/N0/L1/P0)");
 3010    FMQ (    0, 6,  3,10,     Mc, "Intel Mobile Core i*-3000 (Ivy Bridge) / Pentium 900/1000/2000/2100");
 3011    FMQ (    0, 6,  3,10,     dc, "Intel Core i*-3000 (Ivy Bridge)");
 3012    FMQ (    0, 6,  3,10,     sX, "Intel Xeon E3-1100 v2 / E3-1200 v2 (Ivy Bridge)");
 3013    FMQ (    0, 6,  3,10,     dC, "Intel Celeron 1000 / G1600 (Ivy Bridge)"); // only MRG 2019-08-31
 3014    FMQ (    0, 6,  3,10,     dP, "Intel Pentium G1600/G2000/G2100 / Pentium B900C (Ivy Bridge)");
 3015    FM  (    0, 6,  3,10,         "Intel Core (unknown type) (Ivy Bridge)");
 3016    // Intel docs (328899, 328903, 328908) omit the stepping numbers for (0,6),(3,12) C0 & D0.
 3017    // MRG* 2018-03-06 mentions (0,6),(3,12),3, but doesn't specify which stepping name it is.
 3018    // Coreboot* identifies the steppings.
 3019    FMSQ(    0, 6,  3,12,  1, sX, "Intel Xeon E3-1200 v3 (Haswell A0)");
 3020    FMSQ(    0, 6,  3,12,  1, Mc, "Intel Mobile Core i*-4000U (Mobile M) (Haswell A0)");
 3021    FMSQ(    0, 6,  3,12,  1, dc, "Intel Core i*-4000 / Mobile Core i*-4000 (Haswell A0)");
 3022    FMSQ(    0, 6,  3,12,  1, MC, "Intel Mobile Celeron 2900U (Mobile M) (Haswell A0)");
 3023    FMSQ(    0, 6,  3,12,  1, dC, "Intel Celeron G1800 / G2000 (Haswell A0)"); // G2000 only from MRG* 2019-08-31
 3024    FMSQ(    0, 6,  3,12,  1, MP, "Intel Mobile Pentium 3500U / 3600U / 3500Y (Mobile M) (Haswell A0)");
 3025    FMSQ(    0, 6,  3,12,  1, dP, "Intel Pentium G3000 (Haswell A0)");
 3026    FMS (    0, 6,  3,12,  1,     "Intel Core (unknown type) (Haswell A0)");
 3027    FMSQ(    0, 6,  3,12,  2, sX, "Intel Xeon E3-1200 v3 (Haswell B0)");
 3028    FMSQ(    0, 6,  3,12,  2, Mc, "Intel Mobile Core i*-4000U (Mobile M) (Haswell B0)");
 3029    FMSQ(    0, 6,  3,12,  2, dc, "Intel Core i*-4000 / Mobile Core i*-4000 (Haswell B0)");
 3030    FMSQ(    0, 6,  3,12,  2, MC, "Intel Mobile Celeron 2900U (Mobile M) (Haswell B0)");
 3031    FMSQ(    0, 6,  3,12,  2, dC, "Intel Celeron G1800 / G2000 (Haswell B0)"); // G2000 only from MRG* 2019-08-31
 3032    FMSQ(    0, 6,  3,12,  2, MP, "Intel Mobile Pentium 3500U / 3600U / 3500Y (Mobile M) (Haswell B0)");
 3033    FMSQ(    0, 6,  3,12,  2, dP, "Intel Pentium G3000 (Haswell B0)");
 3034    FMS (    0, 6,  3,12,  2,     "Intel Core (unknown type) (Haswell B0)");
 3035    FMSQ(    0, 6,  3,12,  3, sX, "Intel Xeon E3-1200 v3 (Haswell C0)");
 3036    FMSQ(    0, 6,  3,12,  3, Mc, "Intel Mobile Core i*-4000U (Mobile M) (Haswell C0)");
 3037    FMSQ(    0, 6,  3,12,  3, dc, "Intel Core i*-4000 / Mobile Core i*-4000 (Haswell C0)");
 3038    FMSQ(    0, 6,  3,12,  3, MC, "Intel Mobile Celeron 2900U (Mobile M) (Haswell C0)");
 3039    FMSQ(    0, 6,  3,12,  3, dC, "Intel Celeron G1800 / G2000 (Haswell C0)"); // G2000 only from MRG* 2019-08-31
 3040    FMSQ(    0, 6,  3,12,  3, MP, "Intel Mobile Pentium 3500U / 3600U / 3500Y (Mobile M) (Haswell C0)");
 3041    FMSQ(    0, 6,  3,12,  3, dP, "Intel Pentium G3000 (Haswell C0)");
 3042    FMS (    0, 6,  3,12,  3,     "Intel Core (unknown type) (Haswell C0)");
 3043    FMQ (    0, 6,  3,12,     sX, "Intel Xeon E3-1200 v3 (Haswell)");
 3044    FMQ (    0, 6,  3,12,     Mc, "Intel Mobile Core i*-4000U (Mobile M) (Haswell)");
 3045    FMQ (    0, 6,  3,12,     dc, "Intel Core i*-4000 / Mobile Core i*-4000 (Haswell)");
 3046    FMQ (    0, 6,  3,12,     MC, "Intel Mobile Celeron 2900U (Mobile M) (Haswell)");
 3047    FMQ (    0, 6,  3,12,     dC, "Intel Celeron G1800 / G2000 (Haswell)"); // G2000 only from MRG* 2019-08-31
 3048    FMQ (    0, 6,  3,12,     MP, "Intel Mobile Pentium 3500U / 3600U / 3500Y (Mobile M) (Haswell)");
 3049    FMQ (    0, 6,  3,12,     dP, "Intel Pentium G3000 (Haswell)");
 3050    FM  (    0, 6,  3,12,         "Intel Core (unknown type) (Haswell)");
 3051    // Intel docs (330836) omit the stepping numbers for (0,6),(3,13) E0 & F0.
 3052    // MRG* 2019-08-31 mentions stepping 4, but doesn't specify which stepping name it is.
 3053    // Coreboot* identifies the steppings.
 3054    FMSQ(    0, 6,  3,13,  2, dc, "Intel Core i*-5000 (Broadwell-U C0) / Core M (Broadwell-Y C0)");
 3055    FMSQ(    0, 6,  3,13,  2, MC, "Intel Mobile Celeron 3000 (Broadwell-U C0)");
 3056    FMSQ(    0, 6,  3,13,  2, dC, "Intel Celeron 3000 (Broadwell-U C0)");
 3057    FMSQ(    0, 6,  3,13,  2, dP, "Intel Pentium 3700U / 3800U / 3200U (Broadwell-U C0)"); // only MRG* 2018-03-06, 2019-08-31
 3058    FMS (    0, 6,  3,13,  2,     "Intel Core (unknown type) (Broadwell-U/Y C0)");
 3059    FMSQ(    0, 6,  3,13,  3, dc, "Intel Core i*-5000 (Broadwell-U D0) / Core M (Broadwell-Y D0)");
 3060    FMSQ(    0, 6,  3,13,  3, MC, "Intel Mobile Celeron 3000 (Broadwell-U D0)");
 3061    FMSQ(    0, 6,  3,13,  3, dC, "Intel Celeron 3000 (Broadwell-U D0)");
 3062    FMSQ(    0, 6,  3,13,  3, dP, "Intel Pentium 3700U / 3800U / 3200U (Broadwell-U D0)"); // only MRG* 2018-03-06, 2019-08-31
 3063    FMS (    0, 6,  3,13,  3,     "Intel Core (unknown type) (Broadwell-U/Y D0)");
 3064    FMSQ(    0, 6,  3,13,  4, dc, "Intel Core i*-5000 (Broadwell-U E0) / Core M (Broadwell-Y E0)");
 3065    FMSQ(    0, 6,  3,13,  4, MC, "Intel Mobile Celeron 3000 (Broadwell-U E0)");
 3066    FMSQ(    0, 6,  3,13,  4, dC, "Intel Celeron 3000 (Broadwell-U E0)");
 3067    FMSQ(    0, 6,  3,13,  4, dP, "Intel Pentium 3700U / 3800U / 3200U (Broadwell-U E0)"); // only MRG* 2018-03-06, 2019-08-31
 3068    FMS (    0, 6,  3,13,  4,     "Intel Core (unknown type) (Broadwell-U/Y E0)");
 3069    FMQ (    0, 6,  3,13,     dc, "Intel Core i*-5000 (Broadwell-U) / Core M (Broadwell-Y)");
 3070    FMQ (    0, 6,  3,13,     MC, "Intel Mobile Celeron 3000 (Broadwell-U)");
 3071    FMQ (    0, 6,  3,13,     dC, "Intel Celeron 3000 (Broadwell-U)");
 3072    FMQ (    0, 6,  3,13,     dP, "Intel Pentium 3700U / 3800U / 3200U (Broadwell-U)"); // only MRG* 2018-03-06, 2019-08-31
 3073    FM  (    0, 6,  3,13,         "Intel Core (unknown type) (Broadwell-U/Y)");
 3074    // Intel docs (329189, 329368, 329597).
 3075    FMSQ(    0, 6,  3,14,  4, sX, "Intel Xeon E5-1600/E5-2600 v2 (Ivy Bridge-EP C1/M1/S1)");
 3076    FMSQ(    0, 6,  3,14,  4, dc, "Intel Core i*-4000 (Ivy Bridge-E S1)");
 3077    FMS (    0, 6,  3,14,  4,     "Intel Core (unknown type) (Ivy Bridge-EP C1/M1/S1)");
 3078    FMSQ(    0, 6,  3,14,  7, sX, "Intel Xeon E5-4600 / E7-2800 / E7-4800 / E7-8800 v2 (Ivy Bridge-EX D1)"); // E5-4600 names from MRG* 2018-03-06, 2019-08-31
 3079    FMS (    0, 6,  3,14,  7,     "Intel Xeon (unknown type) (Ivy Bridge-EX D1)");
 3080    FMQ (    0, 6,  3,14,     sX, "Intel Xeon E5-1600 / E5-2600 v2 (Ivy Bridge-EP) / Xeon E5-4600 / E7-2800 / E7-4800 / E7-8800 (Ivy Bridge-EX)");
 3081    FMQ (    0, 6,  3,14,     dc, "Intel Core i9-4000 (Ivy Bridge-E)");
 3082    FM  (    0, 6,  3,14,         "Intel Core (unknown type) (Ivy Bridge-E / Ivy Bridge-EP / Ivy Bridge-EX)");
 3083    // Intel docs (330785, 330841, 332317).
 3084    FMSQ(    0, 6,  3,15,  2, dc, "Intel Core i7-5000 Extreme Edition (Haswell-E R2)");
 3085    FMSQ(    0, 6,  3,15,  2, sX, "Intel Xeon E5-x600 v3 (Haswell-EP C1/M1/R2)");
 3086    FMS (    0, 6,  3,15,  2,     "Intel (unknown type) (Haswell C1/M1/R2)");
 3087    FMS (    0, 6,  3,15,  4,     "Intel Xeon E7-4800 / E7-8800 v3 (Haswell-EP E0)");
 3088    FM  (    0, 6,  3,15,         "Intel Core (unknown type) (Haswell R2 / Haswell-EP)");
 3089    // Intel docs (328903) omit the stepping numbers for (0,6),(4,5) C0 & D0.
 3090    // MRG* 2019-08-31 mentions stepping 1, but doesn't specify which stepping name it is.
 3091    // Coreboot* identifies the 0 stepping as B0, but not what the 1 stepping is.
 3092    FMSQ(    0, 6,  4, 5,  0, dc, "Intel Core i*-4000U (Haswell-ULT B0)"); // no docs, but example from Brice Goglin
 3093    FMSQ(    0, 6,  4, 5,  0, Mc, "Intel Mobile Core i*-4000Y (Mobile U/Y) (Haswell-ULT B0)");
 3094    FMSQ(    0, 6,  4, 5,  0, MP, "Intel Mobile Pentium 3500U / 3600U / 3500Y (Mobile U/Y) (Haswell-ULT B0)");
 3095    FMSQ(    0, 6,  4, 5,  0, MC, "Intel Mobile Celeron 2900U (Mobile U/Y) (Haswell-ULT B0)");
 3096    FMS (    0, 6,  4, 5,  0,     "Intel Core (unknown type) (Haswell-ULT B0)");
 3097    FMQ (    0, 6,  4, 5,     dc, "Intel Core i*-4000U (Haswell-ULT)"); // no docs, but example from Brice Goglin
 3098    FMQ (    0, 6,  4, 5,     Mc, "Intel Mobile Core i*-4000Y (Mobile U/Y) (Haswell-ULT)");
 3099    FMQ (    0, 6,  4, 5,     MP, "Intel Mobile Pentium 3500U / 3600U / 3500Y (Mobile U/Y) (Haswell-ULT)");
 3100    FMQ (    0, 6,  4, 5,     MC, "Intel Mobile Celeron 2900U (Mobile U/Y) (Haswell-ULT)");
 3101    FM  (    0, 6,  4, 5,         "Intel Core (unknown type) (Haswell-ULT)");
 3102    // Intel docs (328899,328903) omit the stepping numbers for (0,6),(4,6) C0 & D0.
 3103    // MRG* mentions (0,6),(4,6),1, but doesn't specify which stepping name it is.
 3104    FMQ (    0, 6,  4, 6,     Mc, "Intel Mobile Core i*-4000Y (Mobile H) (Crystal Well)");
 3105    FMQ (    0, 6,  4, 6,     dc, "Intel Core i*-4000 / Mobile Core i*-4000 (Desktop R) (Crystal Well)");
 3106    FMQ (    0, 6,  4, 6,     MP, "Intel Mobile Pentium 3500U / 3600U / 3500Y (Mobile H) (Crystal Well)");
 3107    FMQ (    0, 6,  4, 6,     dC, "Intel Celeron G1800 (Desktop R) (Crystal Well)");
 3108    FMQ (    0, 6,  4, 6,     MC, "Intel Mobile Celeron 2900U (Mobile H) (Crystal Well)");
 3109    FMQ (    0, 6,  4, 6,     dP, "Intel Pentium G3000 (Desktop R) (Crystal Well)");
 3110    FM  (    0, 6,  4, 6,         "Intel Core (unknown type) (Crystal Well)");
 3111    // So far, all these (0,6),(4,7) processors are stepping G0, but the
 3112    // Intel docs (332381, 332382) omit the stepping number for G0.
 3113    // MRG* 2018-03-06 describes Broadwell H 43e.
 3114    FMSQ(    0, 6,  4, 7,  1, dc, "Intel Core i*-5000 (Broadwell G0)");
 3115    FMSQ(    0, 6,  4, 7,  1, Mc, "Intel Mobile Core i7-5000 (Broadwell G0)");
 3116    FMSQ(    0, 6,  4, 7,  1, sX, "Intel Xeon E3-1200 v4 (Broadwell G0)");
 3117    FMS (    0, 6,  4, 7,  1,     "Intel (unknown type) (Broadwell-H G0)");
 3118    FMQ (    0, 6,  4, 7,     dc, "Intel Core i7-5000 (Broadwell)");
 3119    FMQ (    0, 6,  4, 7,     Mc, "Intel Mobile Core i7-5000 (Broadwell)");
 3120    FMQ (    0, 6,  4, 7,     sX, "Intel Xeon E3-1200 v4 (Broadwell)");
 3121    FM  (    0, 6,  4, 7,         "Intel Core (unknown type) (Broadwell)");
 3122    // no spec update; only MSR_CPUID_table* so far
 3123    // MRG* 2018-03-06 mentions steppings 8 and 9, but without names for either.
 3124    FM  (    0, 6,  4,10,         "Intel Atom Z3400 (Merrifield)");
 3125    // Intel docs (332095).
 3126    FMSQ(    0, 6,  4,12,  3, dC, "Intel Celeron N3000 / J3000 (Braswell C0)");
 3127    FMSQ(    0, 6,  4,12,  3, dP, "Intel Pentium N3000 / J3000 (Braswell C0)");
 3128    FMSQ(    0, 6,  4,12,  3, da, "Intel Atom x5-E8000 / x*-Z8000 (Cherry Trail C0)"); // no spec update; only MRG* 2018-03-06, 2019-08-31
 3129    FMS (    0, 6,  4,12,  3,     "Intel Atom (unknown type) (Braswell/Cherry Trail C0)");
 3130    FMSQ(    0, 6,  4,12,  4, dC, "Intel Celeron N3000 / J3000 (Braswell D1)");
 3131    FMSQ(    0, 6,  4,12,  4, dP, "Intel Pentium N3000 / J3000 (Braswell D1)");
 3132    FMSQ(    0, 6,  4,12,  4, da, "Intel Atom x5-E8000 / x*-Z8000 (Cherry Trail D1)"); // no spec update; only MRG* 2018-03-06, 2019-08-31
 3133    FMS (    0, 6,  4,12,  4,     "Intel Atom (unknown type) (Braswell/Cherry Trail D1)");
 3134    FMQ (    0, 6,  4,12,     dC, "Intel Celeron N3000 / J3000 (Braswell)");
 3135    FMQ (    0, 6,  4,12,     dP, "Intel Pentium N3000 / J3000 (Braswell)");
 3136    FMQ (    0, 6,  4,12,     da, "Intel Atom x5-E8000 / x*-Z8000 (Cherry Trail)"); // no spec update; only MRG* 2018-03-06, 2019-08-31
 3137    FM  (    0, 6,  4,12,         "Intel Atom (unknown type) (Braswell/Cherry Trail)");
 3138    // Intel docs (329460, 330061).
 3139    FMS (    0, 6,  4,13,  0,     "Intel Atom C2000 (Avoton A0/A1)");
 3140    FMS (    0, 6,  4,13,  8,     "Intel Atom C2000 (Avoton/Rangeley B0/C0)");
 3141    FM  (    0, 6,  4,13,         "Intel Atom C2000 (Avoton)");
 3142    // Intel docs (332689) omit the stepping numbers for (0,6),(4,14) D1 & K1.
 3143    // MRG* 2018-03-06 mentions (0,6),(4,14),3, but doesn't specify which
 3144    // stepping name it is.
 3145    // Coreboot* identifies the 2 (C0) & 3 (D0) steppings, neither of which is
 3146    // mentioned in (332689).
 3147    // Coreboot* identifies stepping 8 as (Kaby Lake G0). Perhaps they were just
 3148    // early engineering samples of Kaby Lake.
 3149    FMSQ(    0, 6,  4,14,  2, dc, "Intel Core i*-6000U / m*-6Y00 (Skylake C0)");
 3150    FMSQ(    0, 6,  4,14,  2, dP, "Intel Pentium 4405U / Pentium 4405Y (Skylake C0)");
 3151    FMSQ(    0, 6,  4,14,  2, dC, "Intel Celeron 3800U / 39000U (Skylake C0)");
 3152    FMSQ(    0, 6,  4,14,  2, sX, "Intel Xeon E3-1500m (Skylake C0)"); // no spec update; only MSR_CPUID_table* so far
 3153    FMS (    0, 6,  4,14,  2,     "Intel Core (unknown type) (Skylake C0)");
 3154    FMSQ(    0, 6,  4,14,  3, dc, "Intel Core i*-6000U / m*-6Y00 (Skylake D0)");
 3155    FMSQ(    0, 6,  4,14,  3, dP, "Intel Pentium 4405U / Pentium 4405Y (Skylake D0)");
 3156    FMSQ(    0, 6,  4,14,  3, dC, "Intel Celeron 3800U / 39000U (Skylake D0)");
 3157    FMSQ(    0, 6,  4,14,  3, sX, "Intel Xeon E3-1500m (Skylake D0)"); // no spec update; only MSR_CPUID_table* so far
 3158    FMS (    0, 6,  4,14,  3,     "Intel Core (unknown type) (Skylake D0)");
 3159    FMS (    0, 6,  4,14,  8,     "Intel Core (unknown type) (Kaby Lake G0)"); // Coreboot*
 3160    FMQ (    0, 6,  4,14,     dc, "Intel Core i*-6000U / m*-6Y00 (Skylake)");
 3161    FMQ (    0, 6,  4,14,     dP, "Intel Pentium 4405U / Pentium 4405Y (Skylake)");
 3162    FMQ (    0, 6,  4,14,     dC, "Intel Celeron 3800U / 39000U (Skylake)");
 3163    FMQ (    0, 6,  4,14,     sX, "Intel Xeon E3-1500m (Skylake)"); // no spec update; only MSR_CPUID_table* so far
 3164    FM  (    0, 6,  4,14,         "Intel Core (unknown type) (Skylake)");
 3165    // Intel docs (333811, 334165) omit the stepping numbers for (0,6),(4,15)
 3166    // B0, M0 & R0, but (334208) provide some.
 3167    FMSQ(    0, 6,  4,15,  1, dc, "Intel Core i7-6800K / i7-6900K / i7-6900X (Broadwell-E R0)");
 3168    FMQ (    0, 6,  4,15,     dc, "Intel Core i7-6800K / i7-6900K / i7-6900X (Broadwell-E)");
 3169    FMSQ(    0, 6,  4,15,  1, sX, "Intel Xeon E5-1600 / E5-2600 / E5-4600 v4 (Broadwell-E) / E7-4800 / E7-8800 v4 (Broadwell-EX B0)");
 3170    FMQ (    0, 6,  4,15,     sX, "Intel Xeon E5-1600 / E5-2600 / E5-4600 v4 (Broadwell-E) / E7-4800 / E7-8800 v4 (Broadwell-EX)");
 3171    FM  (    0, 6,  4,15,         "Intel Core (unknown type) (Broadwell-E / Broadwell-EX)");
 3172    // Intel docs (335901) omit almost all details for the Core versions of
 3173    // (0,6),(5,5).  But Intel docs (336065: Xeon Scalable steppings 2 & 4,
 3174    // 338848: Xeon Scalable (2nd gen) stepping 7, and 338854: Xeon D-2000
 3175    // stepping 2) provides some.
 3176    // MRG* 2019-11-13 mentions stepping 3, but doesn't mention stepping name.
 3177    // geekbench.com has an "Intel Xeon Gold 6230" example of a stepping 5, but
 3178    // no stepping name.
 3179    FMSQ(    0, 6,  5, 5,  2, sS, "Intel Scalable Bronze/Silver/Gold/Platinum (Skylake B0/L0)");
 3180    FMSQ(    0, 6,  5, 5,  2, sX, "Intel Xeon W 2000 / D-2100 (Skylake B0/L0)");
 3181    FMSQ(    0, 6,  5, 5,  4, sS, "Intel Scalable Bronze/Silver/Gold/Platinum (Skylake H0/M0/U0)");
 3182    FMSQ(    0, 6,  5, 5,  4, sX, "Intel Xeon W 2000 / D-2100 (Skylake H0/M0/U0)"); // D-2100 from MRG* 2018-03-06
 3183    FMSQ(    0, 6,  5, 5,  4, dc, "Intel Core i9-7000X (Skylake-X H0/M0/U0)"); // only from MRG* 2018-03-06
 3184    FMSQ(    0, 6,  5, 5,  6, sS, "Intel Scalable (2nd Gen) Bronze/Silver/Gold/Platinum (Cascade Lake)"); // no docs, but example from Greg Stewart
 3185    FMSQ(    0, 6,  5, 5,  6, sX, "Intel Xeon W 2000 (Cascade Lake)"); // no docs, but example from Greg Stewart
 3186    FMSQ(    0, 6,  5, 5,  7, dc, "Intel Core i*-10000X (Cascade Lake-X B1/L1/R1)"); // no docs, but instlatx64 example
 3187    FMSQ(    0, 6