PageRenderTime 55ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdPartyCode/GotoBLAS-1.26/cpuid_x86.c

https://bitbucket.org/rutad/libs
C | 1163 lines | 1039 code | 103 blank | 21 comment | 193 complexity | f7107c78852ee0e980a1e5156376fffa MD5 | raw file
Possible License(s): BSD-3-Clause, MPL-2.0-no-copyleft-exception, GPL-3.0
  1. /*********************************************************************/
  2. /* */
  3. /* Optimized BLAS libraries */
  4. /* By Kazushige Goto <kgoto@tacc.utexas.edu> */
  5. /* */
  6. /* Copyright (c) The University of Texas, 2005. All rights reserved. */
  7. /* UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING */
  8. /* THIS SOFTWARE AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF */
  9. /* MERCHANTABILITY, FITNESS FOR ANY PARTICULAR PURPOSE, */
  10. /* NON-INFRINGEMENT AND WARRANTIES OF PERFORMANCE, AND ANY WARRANTY */
  11. /* THAT MIGHT OTHERWISE ARISE FROM COURSE OF DEALING OR USAGE OF */
  12. /* TRADE. NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH RESPECT TO */
  13. /* THE USE OF THE SOFTWARE OR DOCUMENTATION. */
  14. /* Under no circumstances shall University be liable for incidental, */
  15. /* special, indirect, direct or consequential damages or loss of */
  16. /* profits, interruption of business, or related expenses which may */
  17. /* arise from use of Software or Documentation, including but not */
  18. /* limited to those resulting from defects in Software and/or */
  19. /* Documentation, or loss or inaccuracy of data of any kind. */
  20. /*********************************************************************/
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include "cpuid.h"
  24. #ifdef __APPLE__
  25. void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx);
  26. #else
  27. static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx){
  28. __asm__ __volatile__
  29. ("cpuid": "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (op) : "cc");
  30. }
  31. #endif
  32. static inline int have_cpuid(void){
  33. int eax, ebx, ecx, edx;
  34. cpuid(0, &eax, &ebx, &ecx, &edx);
  35. return eax;
  36. }
  37. static inline int have_excpuid(void){
  38. int eax, ebx, ecx, edx;
  39. cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
  40. return eax & 0xffff;
  41. }
  42. int get_vendor(void){
  43. int eax, ebx, ecx, edx;
  44. char vendor[13];
  45. cpuid(0, &eax, &ebx, &ecx, &edx);
  46. *(int *)(&vendor[0]) = ebx;
  47. *(int *)(&vendor[4]) = edx;
  48. *(int *)(&vendor[8]) = ecx;
  49. vendor[12] = (char)NULL;
  50. if (!strcmp(vendor, "GenuineIntel")) return VENDOR_INTEL;
  51. if (!strcmp(vendor, " UMC UMC UMC")) return VENDOR_UMC;
  52. if (!strcmp(vendor, "AuthenticAMD")) return VENDOR_AMD;
  53. if (!strcmp(vendor, "CyrixInstead")) return VENDOR_CYRIX;
  54. if (!strcmp(vendor, "NexGenDriven")) return VENDOR_NEXGEN;
  55. if (!strcmp(vendor, "CentaurHauls")) return VENDOR_CENTAUR;
  56. if (!strcmp(vendor, "RiseRiseRise")) return VENDOR_RISE;
  57. if (!strcmp(vendor, " SiS SiS SiS")) return VENDOR_SIS;
  58. if (!strcmp(vendor, "GenuineTMx86")) return VENDOR_TRANSMETA;
  59. if (!strcmp(vendor, "Geode by NSC")) return VENDOR_NSC;
  60. if ((eax == 0) || ((eax & 0x500) != 0)) return VENDOR_INTEL;
  61. return VENDOR_UNKNOWN;
  62. }
  63. int get_cputype(int gettype){
  64. int eax, ebx, ecx, edx;
  65. int extend_family, family;
  66. int extend_model, model;
  67. int type, stepping;
  68. int feature = 0;
  69. cpuid(1, &eax, &ebx, &ecx, &edx);
  70. switch (gettype) {
  71. case GET_EXFAMILY :
  72. return BITMASK(eax, 20, 0xff);
  73. case GET_EXMODEL :
  74. return BITMASK(eax, 16, 0x0f);
  75. case GET_TYPE :
  76. return BITMASK(eax, 12, 0x03);
  77. case GET_FAMILY :
  78. return BITMASK(eax, 8, 0x0f);
  79. case GET_MODEL :
  80. return BITMASK(eax, 4, 0x0f);
  81. case GET_APICID :
  82. return BITMASK(ebx, 24, 0x0f);
  83. case GET_LCOUNT :
  84. return BITMASK(ebx, 16, 0x0f);
  85. case GET_CHUNKS :
  86. return BITMASK(ebx, 8, 0x0f);
  87. case GET_STEPPING :
  88. return BITMASK(eax, 0, 0x0f);
  89. case GET_BLANDID :
  90. return BITMASK(ebx, 0, 0xff);
  91. case GET_NUMSHARE :
  92. if (have_cpuid() < 4) return 0;
  93. cpuid(4, &eax, &ebx, &ecx, &edx);
  94. return BITMASK(eax, 14, 0xfff);
  95. case GET_NUMCORES :
  96. if (have_cpuid() < 4) return 0;
  97. cpuid(4, &eax, &ebx, &ecx, &edx);
  98. return BITMASK(eax, 26, 0x3f);
  99. case GET_FEATURE :
  100. if ((edx & (1 << 3)) != 0) feature |= HAVE_PSE;
  101. if ((edx & (1 << 15)) != 0) feature |= HAVE_CMOV;
  102. if ((edx & (1 << 19)) != 0) feature |= HAVE_CFLUSH;
  103. if ((edx & (1 << 23)) != 0) feature |= HAVE_MMX;
  104. if ((edx & (1 << 25)) != 0) feature |= HAVE_SSE;
  105. if ((edx & (1 << 26)) != 0) feature |= HAVE_SSE2;
  106. if ((edx & (1 << 27)) != 0) {
  107. if (BITMASK(ebx, 16, 0x0f) > 0) feature |= HAVE_HIT;
  108. }
  109. if ((ecx & (1 << 0)) != 0) feature |= HAVE_SSE3;
  110. if ((ecx & (1 << 9)) != 0) feature |= HAVE_SSSE3;
  111. if ((ecx & (1 << 19)) != 0) feature |= HAVE_SSE4_1;
  112. if ((ecx & (1 << 20)) != 0) feature |= HAVE_SSE4_2;
  113. cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
  114. if ((ecx & (1 << 6)) != 0) feature |= HAVE_SSE4A;
  115. if ((ecx & (1 << 7)) != 0) feature |= HAVE_MISALIGNSSE;
  116. if ((edx & (1 << 30)) != 0) feature |= HAVE_3DNOWEX;
  117. if ((edx & (1 << 31)) != 0) feature |= HAVE_3DNOW;
  118. if (have_excpuid() >= 0x1a) {
  119. cpuid(0x8000001a, &eax, &ebx, &ecx, &edx);
  120. if ((eax & (1 << 0)) != 0) feature |= HAVE_128BITFPU;
  121. if ((eax & (1 << 1)) != 0) feature |= HAVE_FASTMOVU;
  122. }
  123. }
  124. return feature;
  125. }
  126. int get_cacheinfo(int type, cache_info_t *cacheinfo){
  127. int eax, ebx, ecx, edx, cpuid_level;
  128. int info[15];
  129. int i;
  130. cache_info_t LC1, LD1, L2, L3,
  131. ITB, DTB, LITB, LDTB,
  132. L2ITB, L2DTB, L2LITB, L2LDTB;
  133. LC1.size = 0; LC1.associative = 0; LC1.linesize = 0; LC1.shared = 0;
  134. LD1.size = 0; LD1.associative = 0; LD1.linesize = 0; LD1.shared = 0;
  135. L2.size = 0; L2.associative = 0; L2.linesize = 0; L2.shared = 0;
  136. L3.size = 0; L3.associative = 0; L3.linesize = 0; L3.shared = 0;
  137. ITB.size = 0; ITB.associative = 0; ITB.linesize = 0; ITB.shared = 0;
  138. DTB.size = 0; DTB.associative = 0; DTB.linesize = 0; DTB.shared = 0;
  139. LITB.size = 0; LITB.associative = 0; LITB.linesize = 0; LITB.shared = 0;
  140. LDTB.size = 0; LDTB.associative = 0; LDTB.linesize = 0; LDTB.shared = 0;
  141. L2ITB.size = 0; L2ITB.associative = 0; L2ITB.linesize = 0; L2ITB.shared = 0;
  142. L2DTB.size = 0; L2DTB.associative = 0; L2DTB.linesize = 0; L2DTB.shared = 0;
  143. L2LITB.size = 0; L2LITB.associative = 0; L2LITB.linesize = 0; L2LITB.shared = 0;
  144. L2LDTB.size = 0; L2LDTB.associative = 0; L2LDTB.linesize = 0; L2LDTB.shared = 0;
  145. cpuid(0, &cpuid_level, &ebx, &ecx, &edx);
  146. if (cpuid_level > 1) {
  147. cpuid(2, &eax, &ebx, &ecx, &edx);
  148. info[ 0] = BITMASK(eax, 8, 0xff);
  149. info[ 1] = BITMASK(eax, 16, 0xff);
  150. info[ 2] = BITMASK(eax, 24, 0xff);
  151. info[ 3] = BITMASK(ebx, 0, 0xff);
  152. info[ 4] = BITMASK(ebx, 8, 0xff);
  153. info[ 5] = BITMASK(ebx, 16, 0xff);
  154. info[ 6] = BITMASK(ebx, 24, 0xff);
  155. info[ 7] = BITMASK(ecx, 0, 0xff);
  156. info[ 8] = BITMASK(ecx, 8, 0xff);
  157. info[ 9] = BITMASK(ecx, 16, 0xff);
  158. info[10] = BITMASK(ecx, 24, 0xff);
  159. info[11] = BITMASK(edx, 0, 0xff);
  160. info[12] = BITMASK(edx, 8, 0xff);
  161. info[13] = BITMASK(edx, 16, 0xff);
  162. info[14] = BITMASK(edx, 24, 0xff);
  163. for (i = 0; i < 15; i++){
  164. switch (info[i]){
  165. /* This table is from http://www.sandpile.org/ia32/cpuid.htm */
  166. case 0x01 :
  167. ITB.size = 4;
  168. ITB.associative = 4;
  169. ITB.linesize = 32;
  170. break;
  171. case 0x02 :
  172. LITB.size = 4096;
  173. LITB.associative = 0;
  174. LITB.linesize = 2;
  175. break;
  176. case 0x03 :
  177. DTB.size = 4;
  178. DTB.associative = 4;
  179. DTB.linesize = 64;
  180. break;
  181. case 0x04 :
  182. LDTB.size = 4096;
  183. LDTB.associative = 4;
  184. LDTB.linesize = 8;
  185. break;
  186. case 0x05 :
  187. LDTB.size = 4096;
  188. LDTB.associative = 4;
  189. LDTB.linesize = 32;
  190. break;
  191. case 0x06 :
  192. LC1.size = 8;
  193. LC1.associative = 4;
  194. LC1.linesize = 32;
  195. break;
  196. case 0x08 :
  197. LC1.size = 16;
  198. LC1.associative = 4;
  199. LC1.linesize = 32;
  200. break;
  201. case 0x0a :
  202. LD1.size = 8;
  203. LD1.associative = 2;
  204. LD1.linesize = 32;
  205. break;
  206. case 0x0c :
  207. LD1.size = 16;
  208. LD1.associative = 4;
  209. LD1.linesize = 32;
  210. break;
  211. case 0x10 :
  212. LD1.size = 16;
  213. LD1.associative = 4;
  214. LD1.linesize = 32;
  215. break;
  216. case 0x15 :
  217. LC1.size = 16;
  218. LC1.associative = 4;
  219. LC1.linesize = 32;
  220. break;
  221. case 0x1a :
  222. L2.size = 96;
  223. L2.associative = 6;
  224. L2.linesize = 64;
  225. break;
  226. case 0x22 :
  227. L3.size = 512;
  228. L3.associative = 4;
  229. L3.linesize = 64;
  230. break;
  231. case 0x23 :
  232. L3.size = 1024;
  233. L3.associative = 8;
  234. L3.linesize = 64;
  235. break;
  236. case 0x25 :
  237. L3.size = 2048;
  238. L3.associative = 8;
  239. L3.linesize = 64;
  240. break;
  241. case 0x29 :
  242. L3.size = 4096;
  243. L3.associative = 8;
  244. L3.linesize = 64;
  245. break;
  246. case 0x2c :
  247. LD1.size = 32;
  248. LD1.associative = 8;
  249. LD1.linesize = 64;
  250. break;
  251. case 0x30 :
  252. LC1.size = 32;
  253. LC1.associative = 8;
  254. LC1.linesize = 64;
  255. break;
  256. case 0x39 :
  257. L2.size = 128;
  258. L2.associative = 4;
  259. L2.linesize = 64;
  260. break;
  261. case 0x3a :
  262. L2.size = 192;
  263. L2.associative = 6;
  264. L2.linesize = 64;
  265. break;
  266. case 0x3b :
  267. L2.size = 128;
  268. L2.associative = 2;
  269. L2.linesize = 64;
  270. break;
  271. case 0x3c :
  272. L2.size = 256;
  273. L2.associative = 4;
  274. L2.linesize = 64;
  275. break;
  276. case 0x3d :
  277. L2.size = 384;
  278. L2.associative = 6;
  279. L2.linesize = 64;
  280. break;
  281. case 0x3e :
  282. L2.size = 512;
  283. L2.associative = 4;
  284. L2.linesize = 64;
  285. break;
  286. case 0x41 :
  287. L2.size = 128;
  288. L2.associative = 4;
  289. L2.linesize = 32;
  290. break;
  291. case 0x42 :
  292. L2.size = 256;
  293. L2.associative = 4;
  294. L2.linesize = 32;
  295. break;
  296. case 0x43 :
  297. L2.size = 512;
  298. L2.associative = 4;
  299. L2.linesize = 32;
  300. break;
  301. case 0x44 :
  302. L2.size = 1024;
  303. L2.associative = 4;
  304. L2.linesize = 32;
  305. break;
  306. case 0x45 :
  307. L2.size = 2048;
  308. L2.associative = 4;
  309. L2.linesize = 32;
  310. break;
  311. case 0x46 :
  312. L3.size = 4096;
  313. L3.associative = 4;
  314. L3.linesize = 64;
  315. break;
  316. case 0x47 :
  317. L3.size = 8192;
  318. L3.associative = 8;
  319. L3.linesize = 64;
  320. break;
  321. case 0x49 :
  322. L2.size = 4096;
  323. L2.associative = 16;
  324. L2.linesize = 64;
  325. break;
  326. case 0x4a :
  327. L3.size = 6144;
  328. L3.associative = 12;
  329. L3.linesize = 64;
  330. break;
  331. case 0x4b :
  332. L3.size = 8192;
  333. L3.associative = 16;
  334. L3.linesize = 64;
  335. break;
  336. case 0x4c :
  337. L3.size = 12280;
  338. L3.associative = 12;
  339. L3.linesize = 64;
  340. break;
  341. case 0x4d :
  342. L3.size = 16384;
  343. L3.associative = 16;
  344. L3.linesize = 64;
  345. break;
  346. case 0x4e :
  347. L2.size = 6144;
  348. L2.associative = 24;
  349. L2.linesize = 64;
  350. break;
  351. case 0x50 :
  352. ITB.size = 4;
  353. ITB.associative = 0;
  354. ITB.linesize = 64;
  355. LITB.size = 4096;
  356. LITB.associative = 0;
  357. LITB.linesize = 64;
  358. LITB.shared = 1;
  359. break;
  360. case 0x51 :
  361. ITB.size = 4;
  362. ITB.associative = 0;
  363. ITB.linesize = 128;
  364. LITB.size = 4096;
  365. LITB.associative = 0;
  366. LITB.linesize = 128;
  367. LITB.shared = 1;
  368. break;
  369. case 0x52 :
  370. ITB.size = 4;
  371. ITB.associative = 0;
  372. ITB.linesize = 256;
  373. LITB.size = 4096;
  374. LITB.associative = 0;
  375. LITB.linesize = 256;
  376. LITB.shared = 1;
  377. break;
  378. case 0x56 :
  379. LDTB.size = 4096;
  380. LDTB.associative = 4;
  381. LDTB.linesize = 16;
  382. break;
  383. case 0x57 :
  384. LDTB.size = 4096;
  385. LDTB.associative = 4;
  386. LDTB.linesize = 16;
  387. break;
  388. case 0x5b :
  389. DTB.size = 4;
  390. DTB.associative = 0;
  391. DTB.linesize = 64;
  392. LDTB.size = 4096;
  393. LDTB.associative = 0;
  394. LDTB.linesize = 64;
  395. LDTB.shared = 1;
  396. break;
  397. case 0x5c :
  398. DTB.size = 4;
  399. DTB.associative = 0;
  400. DTB.linesize = 128;
  401. LDTB.size = 4096;
  402. LDTB.associative = 0;
  403. LDTB.linesize = 128;
  404. LDTB.shared = 1;
  405. break;
  406. case 0x5d :
  407. DTB.size = 4;
  408. DTB.associative = 0;
  409. DTB.linesize = 256;
  410. LDTB.size = 4096;
  411. LDTB.associative = 0;
  412. LDTB.linesize = 256;
  413. LDTB.shared = 1;
  414. break;
  415. case 0x60 :
  416. LD1.size = 16;
  417. LD1.associative = 8;
  418. LD1.linesize = 64;
  419. break;
  420. case 0x66 :
  421. LD1.size = 8;
  422. LD1.associative = 4;
  423. LD1.linesize = 64;
  424. break;
  425. case 0x67 :
  426. LD1.size = 16;
  427. LD1.associative = 4;
  428. LD1.linesize = 64;
  429. break;
  430. case 0x68 :
  431. LD1.size = 32;
  432. LD1.associative = 4;
  433. LD1.linesize = 64;
  434. break;
  435. case 0x70 :
  436. LC1.size = 12;
  437. LC1.associative = 8;
  438. break;
  439. case 0x71 :
  440. LC1.size = 16;
  441. LC1.associative = 8;
  442. break;
  443. case 0x72 :
  444. LC1.size = 32;
  445. LC1.associative = 8;
  446. break;
  447. case 0x73 :
  448. LC1.size = 64;
  449. LC1.associative = 8;
  450. break;
  451. case 0x77 :
  452. LC1.size = 16;
  453. LC1.associative = 4;
  454. LC1.linesize = 64;
  455. break;
  456. case 0x78 :
  457. L2.size = 1024;
  458. L2.associative = 4;
  459. L2.linesize = 64;
  460. break;
  461. case 0x79 :
  462. L2.size = 128;
  463. L2.associative = 8;
  464. L2.linesize = 64;
  465. break;
  466. case 0x7a :
  467. L2.size = 256;
  468. L2.associative = 8;
  469. L2.linesize = 64;
  470. break;
  471. case 0x7b :
  472. L2.size = 512;
  473. L2.associative = 8;
  474. L2.linesize = 64;
  475. break;
  476. case 0x7c :
  477. L2.size = 1024;
  478. L2.associative = 8;
  479. L2.linesize = 64;
  480. break;
  481. case 0x7d :
  482. L2.size = 2048;
  483. L2.associative = 8;
  484. L2.linesize = 64;
  485. break;
  486. case 0x7e :
  487. L2.size = 256;
  488. L2.associative = 8;
  489. L2.linesize = 128;
  490. break;
  491. case 0x7f :
  492. L2.size = 512;
  493. L2.associative = 2;
  494. L2.linesize = 64;
  495. break;
  496. case 0x81 :
  497. L2.size = 128;
  498. L2.associative = 8;
  499. L2.linesize = 32;
  500. break;
  501. case 0x82 :
  502. L2.size = 256;
  503. L2.associative = 8;
  504. L2.linesize = 32;
  505. break;
  506. case 0x83 :
  507. L2.size = 512;
  508. L2.associative = 8;
  509. L2.linesize = 32;
  510. break;
  511. case 0x84 :
  512. L2.size = 1024;
  513. L2.associative = 8;
  514. L2.linesize = 32;
  515. break;
  516. case 0x85 :
  517. L2.size = 2048;
  518. L2.associative = 8;
  519. L2.linesize = 32;
  520. break;
  521. case 0x86 :
  522. L2.size = 512;
  523. L2.associative = 4;
  524. L2.linesize = 64;
  525. break;
  526. case 0x87 :
  527. L2.size = 1024;
  528. L2.associative = 8;
  529. L2.linesize = 64;
  530. break;
  531. case 0x88 :
  532. L3.size = 2048;
  533. L3.associative = 4;
  534. L3.linesize = 64;
  535. break;
  536. case 0x89 :
  537. L3.size = 4096;
  538. L3.associative = 4;
  539. L3.linesize = 64;
  540. break;
  541. case 0x8a :
  542. L3.size = 8192;
  543. L3.associative = 4;
  544. L3.linesize = 64;
  545. break;
  546. case 0x8d :
  547. L3.size = 3096;
  548. L3.associative = 12;
  549. L3.linesize = 128;
  550. break;
  551. case 0x90 :
  552. ITB.size = 4;
  553. ITB.associative = 0;
  554. ITB.linesize = 64;
  555. break;
  556. case 0x96 :
  557. DTB.size = 4;
  558. DTB.associative = 0;
  559. DTB.linesize = 32;
  560. break;
  561. case 0x9b :
  562. L2DTB.size = 4;
  563. L2DTB.associative = 0;
  564. L2DTB.linesize = 96;
  565. break;
  566. case 0xb0 :
  567. ITB.size = 4;
  568. ITB.associative = 4;
  569. ITB.linesize = 128;
  570. break;
  571. case 0xb1 :
  572. LITB.size = 4096;
  573. LITB.associative = 4;
  574. LITB.linesize = 4;
  575. break;
  576. case 0xb3 :
  577. DTB.size = 4;
  578. DTB.associative = 4;
  579. DTB.linesize = 128;
  580. break;
  581. case 0xb4 :
  582. DTB.size = 4;
  583. DTB.associative = 4;
  584. DTB.linesize = 256;
  585. break;
  586. }
  587. }
  588. }
  589. if (get_vendor() == VENDOR_INTEL) {
  590. cpuid(0x80000000, &cpuid_level, &ebx, &ecx, &edx);
  591. if (cpuid_level >= 0x80000006) {
  592. cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
  593. L2.size = BITMASK(ecx, 16, 0xffff);
  594. L2.associative = BITMASK(ecx, 12, 0x0f);
  595. L2.linesize = BITMASK(ecx, 0, 0xff);
  596. }
  597. }
  598. if ((get_vendor() == VENDOR_AMD) || (get_vendor() == VENDOR_CENTAUR)) {
  599. cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
  600. LDTB.size = 4096;
  601. LDTB.associative = BITMASK(eax, 24, 0xff);
  602. if (LDTB.associative == 0xff) LDTB.associative = 0;
  603. LDTB.linesize = BITMASK(eax, 16, 0xff);
  604. LITB.size = 4096;
  605. LITB.associative = BITMASK(eax, 8, 0xff);
  606. if (LITB.associative == 0xff) LITB.associative = 0;
  607. LITB.linesize = BITMASK(eax, 0, 0xff);
  608. DTB.size = 4;
  609. DTB.associative = BITMASK(ebx, 24, 0xff);
  610. if (DTB.associative == 0xff) DTB.associative = 0;
  611. DTB.linesize = BITMASK(ebx, 16, 0xff);
  612. ITB.size = 4;
  613. ITB.associative = BITMASK(ebx, 8, 0xff);
  614. if (ITB.associative == 0xff) ITB.associative = 0;
  615. ITB.linesize = BITMASK(ebx, 0, 0xff);
  616. LD1.size = BITMASK(ecx, 24, 0xff);
  617. LD1.associative = BITMASK(ecx, 16, 0xff);
  618. if (LD1.associative == 0xff) LD1.associative = 0;
  619. LD1.linesize = BITMASK(ecx, 0, 0xff);
  620. LC1.size = BITMASK(ecx, 24, 0xff);
  621. LC1.associative = BITMASK(ecx, 16, 0xff);
  622. if (LC1.associative == 0xff) LC1.associative = 0;
  623. LC1.linesize = BITMASK(ecx, 0, 0xff);
  624. cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
  625. L2LDTB.size = 4096;
  626. L2LDTB.associative = BITMASK(eax, 24, 0xff);
  627. if (L2LDTB.associative == 0xff) L2LDTB.associative = 0;
  628. L2LDTB.linesize = BITMASK(eax, 16, 0xff);
  629. L2LITB.size = 4096;
  630. L2LITB.associative = BITMASK(eax, 8, 0xff);
  631. if (L2LITB.associative == 0xff) L2LITB.associative = 0;
  632. L2LITB.linesize = BITMASK(eax, 0, 0xff);
  633. L2DTB.size = 4;
  634. L2DTB.associative = BITMASK(ebx, 24, 0xff);
  635. if (L2DTB.associative == 0xff) L2DTB.associative = 0;
  636. L2DTB.linesize = BITMASK(ebx, 16, 0xff);
  637. L2ITB.size = 4;
  638. L2ITB.associative = BITMASK(ebx, 8, 0xff);
  639. if (L2ITB.associative == 0xff) L2ITB.associative = 0;
  640. L2ITB.linesize = BITMASK(ebx, 0, 0xff);
  641. L2.size = BITMASK(ecx, 16, 0xffff);
  642. L2.associative = BITMASK(ecx, 12, 0xf);
  643. if (L2.associative == 0xff) L2.associative = 0;
  644. L2.linesize = BITMASK(ecx, 0, 0xff);
  645. }
  646. switch (type) {
  647. case CACHE_INFO_L1_I :
  648. *cacheinfo = LC1;
  649. break;
  650. case CACHE_INFO_L1_D :
  651. *cacheinfo = LD1;
  652. break;
  653. case CACHE_INFO_L2 :
  654. *cacheinfo = L2;
  655. break;
  656. case CACHE_INFO_L3 :
  657. *cacheinfo = L3;
  658. break;
  659. case CACHE_INFO_L1_DTB :
  660. *cacheinfo = DTB;
  661. break;
  662. case CACHE_INFO_L1_ITB :
  663. *cacheinfo = ITB;
  664. break;
  665. case CACHE_INFO_L1_LDTB :
  666. *cacheinfo = LDTB;
  667. break;
  668. case CACHE_INFO_L1_LITB :
  669. *cacheinfo = LITB;
  670. break;
  671. case CACHE_INFO_L2_DTB :
  672. *cacheinfo = L2DTB;
  673. break;
  674. case CACHE_INFO_L2_ITB :
  675. *cacheinfo = L2ITB;
  676. break;
  677. case CACHE_INFO_L2_LDTB :
  678. *cacheinfo = L2LDTB;
  679. break;
  680. case CACHE_INFO_L2_LITB :
  681. *cacheinfo = L2LITB;
  682. break;
  683. }
  684. return 0;
  685. }
  686. int get_cpuname(void){
  687. int family, exfamily, model, vendor, exmodel;
  688. if (!have_cpuid()) return CPUTYPE_80386;
  689. family = get_cputype(GET_FAMILY);
  690. exfamily = get_cputype(GET_EXFAMILY);
  691. model = get_cputype(GET_MODEL);
  692. exmodel = get_cputype(GET_EXMODEL);
  693. vendor = get_vendor();
  694. if (vendor == VENDOR_INTEL){
  695. switch (family) {
  696. case 0x4:
  697. return CPUTYPE_80486;
  698. case 0x5:
  699. return CPUTYPE_PENTIUM;
  700. case 0x6:
  701. switch (exmodel) {
  702. case 0:
  703. if ((model >= 3) && (model <= 6)) return CPUTYPE_PENTIUM2;
  704. if (((model >= 7) && (model <= 8)) ||
  705. ((model >= 10) && (model <= 11))) return CPUTYPE_PENTIUM3;
  706. if ((model == 9) ||
  707. ((model >= 13) && (model <= 14))) return CPUTYPE_PENTIUMM;
  708. if (model == 15) return CPUTYPE_CORE2;
  709. break;
  710. case 1:
  711. if (model == 6) return CPUTYPE_CORE2;
  712. if (model == 7) return CPUTYPE_PENRYN;
  713. break;
  714. }
  715. break;
  716. case 0x7:
  717. return CPUTYPE_ITANIUM;
  718. case 0xf:
  719. switch (exfamily) {
  720. case 0 :
  721. return CPUTYPE_PENTIUM4;
  722. case 1 :
  723. return CPUTYPE_ITANIUM;
  724. }
  725. break;
  726. }
  727. return CPUTYPE_INTEL_UNKNOWN;
  728. }
  729. if (vendor == VENDOR_AMD){
  730. switch (family) {
  731. case 0x4:
  732. return CPUTYPE_AMD5X86;
  733. case 0x5:
  734. return CPUTYPE_AMDK6;
  735. case 0x6:
  736. return CPUTYPE_ATHLON;
  737. case 0xf:
  738. switch (exfamily) {
  739. case 0 :
  740. return CPUTYPE_OPTERON;
  741. case 1 :
  742. return CPUTYPE_BARCELONA;
  743. }
  744. break;
  745. }
  746. return CPUTYPE_AMD_UNKNOWN;
  747. }
  748. if (vendor == VENDOR_CYRIX){
  749. switch (family) {
  750. case 0x4:
  751. return CPUTYPE_CYRIX5X86;
  752. case 0x5:
  753. return CPUTYPE_CYRIXM1;
  754. case 0x6:
  755. return CPUTYPE_CYRIXM2;
  756. }
  757. return CPUTYPE_CYRIX_UNKNOWN;
  758. }
  759. if (vendor == VENDOR_NEXGEN){
  760. switch (family) {
  761. case 0x5:
  762. return CPUTYPE_NEXGENNX586;
  763. }
  764. return CPUTYPE_NEXGEN_UNKNOWN;
  765. }
  766. if (vendor == VENDOR_CENTAUR){
  767. switch (family) {
  768. case 0x5:
  769. return CPUTYPE_CENTAURC6;
  770. }
  771. return CPUTYPE_VIAC3;
  772. }
  773. if (vendor == VENDOR_RISE){
  774. switch (family) {
  775. case 0x5:
  776. return CPUTYPE_RISEMP6;
  777. }
  778. return CPUTYPE_RISE_UNKNOWN;
  779. }
  780. if (vendor == VENDOR_SIS){
  781. switch (family) {
  782. case 0x5:
  783. return CPUTYPE_SYS55X;
  784. }
  785. return CPUTYPE_SIS_UNKNOWN;
  786. }
  787. if (vendor == VENDOR_TRANSMETA){
  788. switch (family) {
  789. case 0x5:
  790. return CPUTYPE_CRUSOETM3X;
  791. }
  792. return CPUTYPE_TRANSMETA_UNKNOWN;
  793. }
  794. if (vendor == VENDOR_NSC){
  795. switch (family) {
  796. case 0x5:
  797. return CPUTYPE_NSGEODE;
  798. }
  799. return CPUTYPE_NSC_UNKNOWN;
  800. }
  801. return CPUTYPE_UNKNOWN;
  802. }
  803. static char *cpuname[] = {
  804. "UNKNOWN",
  805. "INTEL_UNKNOWN",
  806. "UMC_UNKNOWN",
  807. "AMD_UNKNOWN",
  808. "CYRIX_UNKNOWN",
  809. "NEXGEN_UNKNOWN",
  810. "CENTAUR_UNKNOWN",
  811. "RISE_UNKNOWN",
  812. "SIS_UNKNOWN",
  813. "TRANSMETA_UNKNOWN",
  814. "NSC_UNKNOWN",
  815. "80386",
  816. "80486",
  817. "PENTIUM",
  818. "PENTIUM2",
  819. "PENTIUM3",
  820. "PENTIUMM",
  821. "PENTIUM4",
  822. "CORE2",
  823. "PENRYN",
  824. "ITANIUM",
  825. "ITANIUM2",
  826. "5X86",
  827. "K6",
  828. "ATHLON",
  829. "DURON",
  830. "OPTERON",
  831. "BARCELONA",
  832. "CYRIX5X86",
  833. "CYRIXM1",
  834. "CYRIXM2",
  835. "NEXGENNX586",
  836. "CENTAURC6",
  837. "RISEMP6",
  838. "SYS55X",
  839. "TM3X00",
  840. "NSGEODE",
  841. "VIAC3",
  842. };
  843. static char *lowercpuname[] = {
  844. "unknown",
  845. "intel_unknown",
  846. "umc_unknown",
  847. "amd_unknown",
  848. "cyrix_unknown",
  849. "nexgen_unknown",
  850. "centaur_unknown",
  851. "rise_unknown",
  852. "sis_unknown",
  853. "transmeta_unknown",
  854. "nsc_unknown",
  855. "80386",
  856. "80486",
  857. "pentium",
  858. "pentium2",
  859. "pentium3",
  860. "pentiumm",
  861. "pentium4",
  862. "core2",
  863. "penryn",
  864. "itanium",
  865. "itanium2",
  866. "5x86",
  867. "k6",
  868. "athlon",
  869. "duron",
  870. "opteron",
  871. "barcelona",
  872. "cyrix5x86",
  873. "cyrixm1",
  874. "cyrixm2",
  875. "nexgennx586",
  876. "centaurc6",
  877. "risemp6",
  878. "sys55x",
  879. "tms3x00",
  880. "nsgeode",
  881. };
  882. static char *corename[] = {
  883. "UNKOWN",
  884. "80486",
  885. "P5",
  886. "KATMAI",
  887. "COPPERMINE",
  888. "NORTHWOOD",
  889. "PRESCOTT",
  890. "BANIAS",
  891. "ATHLON",
  892. "OPTERON",
  893. "BARCELONA",
  894. "VIAC3",
  895. "YONAH",
  896. "CORE2",
  897. "PENRYN",
  898. };
  899. static char *corename_lower[] = {
  900. "unknown",
  901. "80486",
  902. "p5",
  903. "katmai",
  904. "coppermine",
  905. "northwood",
  906. "prescott",
  907. "banias",
  908. "athlon",
  909. "opteron",
  910. "barcelona",
  911. "viac3",
  912. "yonah",
  913. "core2",
  914. "penryn",
  915. };
  916. char *get_cpunamechar(void){
  917. return cpuname[get_cpuname()];
  918. }
  919. char *get_lower_cpunamechar(void){
  920. return lowercpuname[get_cpuname()];
  921. }
  922. int get_coretype(void){
  923. int family, exfamily, model, exmodel, vendor;
  924. if (!have_cpuid()) return CORE_80486;
  925. family = get_cputype(GET_FAMILY);
  926. exfamily = get_cputype(GET_EXFAMILY);
  927. model = get_cputype(GET_MODEL);
  928. exmodel = get_cputype(GET_EXMODEL);
  929. vendor = get_vendor();
  930. if (vendor == VENDOR_INTEL){
  931. switch (family) {
  932. case 0x4:
  933. return CORE_80486;
  934. case 0x5:
  935. return CORE_P5;
  936. case 0x6:
  937. switch (exmodel) {
  938. case 0:
  939. if (model <= 0x7) return CORE_KATMAI;
  940. if ((model == 0x8) || (model == 0xa) || (model == 0xb)) return CORE_COPPERMINE;
  941. if ((model == 0x9) || (model == 0xd)) return CORE_BANIAS;
  942. #if 0
  943. if (model == 14) return CORE_YONAH;
  944. #else
  945. if (model == 14) return CORE_BANIAS;
  946. #endif
  947. if (model == 15) return CORE_CORE2;
  948. return CORE_UNKNOWN;
  949. case 1:
  950. if (model == 6) return CORE_CORE2;
  951. if (model == 7) return CORE_PENRYN;
  952. return CORE_UNKNOWN;
  953. }
  954. case 0xf:
  955. if (model <= 0x2) return CORE_NORTHWOOD;
  956. return CORE_PRESCOTT;
  957. }
  958. }
  959. if (vendor == VENDOR_AMD){
  960. if (family <= 0x5) return CORE_80486;
  961. if (family <= 0xe) return CORE_ATHLON;
  962. if (family <= 0xf){
  963. if (exfamily == 0) return CORE_OPTERON; else return CORE_BARCELONA;
  964. }
  965. }
  966. if (vendor == VENDOR_CENTAUR) return CORE_VIAC3;
  967. return CORE_UNKNOWN;
  968. }
  969. void get_cpuconfig(void){
  970. cache_info_t info;
  971. int features;
  972. #ifndef __64BIT__
  973. printf("-DARCH_X86 ");
  974. #else
  975. printf("-DARCH_X86_64 ");
  976. #endif
  977. printf("-D%s ", cpuname[get_cpuname()]);
  978. get_cacheinfo(CACHE_INFO_L1_I, &info);
  979. if (info.size > 0) {
  980. printf("-DL1_CODE_SIZE=%d ", info.size * 1024);
  981. printf("-DL1_CODE_ASSOCIATIVE=%d ", info.associative);
  982. printf("-DL1_CODE_LINESIZE=%d ", info.linesize);
  983. }
  984. get_cacheinfo(CACHE_INFO_L1_D, &info);
  985. if (info.size > 0) {
  986. printf("-DL1_DATA_SIZE=%d ", info.size * 1024);
  987. printf("-DL1_DATA_ASSOCIATIVE=%d ", info.associative);
  988. printf("-DL1_DATA_LINESIZE=%d ", info.linesize);
  989. }
  990. get_cacheinfo(CACHE_INFO_L2, &info);
  991. if (info.size > 0) {
  992. printf("-DL2_SIZE=%d ", info.size * 1024);
  993. printf("-DL2_ASSOCIATIVE=%d ", info.associative);
  994. printf("-DL2_LINESIZE=%d ", info.linesize);
  995. }
  996. get_cacheinfo(CACHE_INFO_L3, &info);
  997. if (info.size > 0) {
  998. printf("-DL3_SIZE=%d ", info.size * 1024);
  999. printf("-DL3_ASSOCIATIVE=%d ", info.associative);
  1000. printf("-DL3_LINESIZE=%d ", info.linesize);
  1001. }
  1002. get_cacheinfo(CACHE_INFO_L1_ITB, &info);
  1003. if (info.size > 0) {
  1004. printf("-DITB_SIZE=%d ", info.size * 1024);
  1005. printf("-DITB_ASSOCIATIVE=%d ", info.associative);
  1006. printf("-DITB_ENTRIES=%d ", info.linesize);
  1007. }
  1008. get_cacheinfo(CACHE_INFO_L1_DTB, &info);
  1009. if (info.size > 0) {
  1010. printf("-DDTB_SIZE=%d ", info.size * 1024);
  1011. printf("-DDTB_ASSOCIATIVE=%d ", info.associative);
  1012. printf("-DDTB_ENTRIES=%d ", info.linesize);
  1013. }
  1014. features = get_cputype(GET_FEATURE);
  1015. if (features & HAVE_CMOV ) printf("-DHAVE_CMOV ");
  1016. if (features & HAVE_MMX ) printf("-DHAVE_MMX ");
  1017. if (features & HAVE_SSE ) printf("-DHAVE_SSE ");
  1018. if (features & HAVE_SSE2 ) printf("-DHAVE_SSE2 ");
  1019. if (features & HAVE_SSE3 ) printf("-DHAVE_SSE3 ");
  1020. if (features & HAVE_SSSE3) printf("-DHAVE_SSSE3 ");
  1021. if (features & HAVE_SSE4_1) printf("-DHAVE_SSE4_1 ");
  1022. if (features & HAVE_SSE4_2) printf("-DHAVE_SSE4_2 ");
  1023. if (features & HAVE_SSE4A) printf("-DHAVE_SSE4A ");
  1024. if (features & HAVE_SSE5 ) printf("-DHAVE_SSSE5 ");
  1025. if (features & HAVE_3DNOWEX) printf("-DHAVE_3DNOWEX ");
  1026. if (features & HAVE_3DNOW) printf("-DHAVE_3DNOW ");
  1027. if (features & HAVE_CFLUSH) printf("-DHAVE_CFLUSH ");
  1028. if (features & HAVE_HIT) printf("-DHAVE_HIT=1 ");
  1029. if (features & HAVE_MISALIGNSSE) printf("-DHAVE_MISALIGNSSE ");
  1030. if (features & HAVE_128BITFPU) printf("-DHAVE_128BITFPU ");
  1031. if (features & HAVE_FASTMOVU) printf("-DHAVE_FASTMOVU ");
  1032. printf("-DNUM_SHAREDCACHE=%d ", get_cputype(GET_NUMSHARE) + 1);
  1033. printf("-DNUM_CORES=%d ", get_cputype(GET_NUMCORES) + 1);
  1034. features = get_coretype();
  1035. if (features > 0) printf("-DCORE_%s ", corename[features]);
  1036. printf("\n");
  1037. }
  1038. void get_architecture(void){
  1039. #ifndef __64BIT__
  1040. printf("X86");
  1041. #else
  1042. printf("X86_64");
  1043. #endif
  1044. }
  1045. void get_subarchitecture(void){
  1046. printf("%s", get_cpunamechar());
  1047. }
  1048. void get_subdirname(void){
  1049. #ifndef __64BIT__
  1050. printf("x86");
  1051. #else
  1052. printf("x86_64");
  1053. #endif
  1054. }
  1055. char *get_corename(void){
  1056. return corename[get_coretype()];
  1057. }
  1058. void get_libname(void){
  1059. printf("%s", corename_lower[get_coretype()]);
  1060. }