Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

402 lines
12 KiB

  1. /*** ***/
  2. /*** INTEL CORPORATION PROPRIETARY INFORMATION ***/
  3. /*** ***/
  4. /*** This software is supplied under the terms of a license ***/
  5. /*** agreement or nondisclosure agreement with Intel Corporation ***/
  6. /*** and may not be copied or disclosed except in accordance with ***/
  7. /*** the terms of that agreement. ***/
  8. /*** Copyright (c) 1992,1993,1994,1995,1996,1997,1998,1999,2000 Intel Corporation. ***/
  9. /*** ***/
  10. /* tree_builder.c */
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include "builder_info.h"
  15. #include "tree_builder.h"
  16. #include "tree.h"
  17. #include "deccpu_emdb.h"
  18. #include "dec_ign_emdb.h"
  19. #define FUNC
  20. #define START_BIT 6 /* start bit of extension calculations, after qp */
  21. #define MAX_NODES 10000 /* empirical desicion of tree size */
  22. unsigned int next_free_node = 0; /* global variable, which points to the next
  23. free node at all times. At the end of
  24. build_tree(), it holds the number of
  25. entries in the tree */
  26. U64 ONE64 = IEL_CONST64(1, 0);
  27. U64 emdb_ext_values[DEC_IGN_NUM_INST];
  28. short cover_emdb_lines[DEC_IGN_NUM_INST];
  29. Internal_node_t tree[MAX_NODES]; /* change this when number is known */
  30. /***********************************************************************
  31. main - this function calculates the value of the extensions for each
  32. emdb line, builds the decision tree, and prints em_decision_tree
  33. in decision_tree.c.
  34. ***********************************************************************/
  35. FUNC void __cdecl main(int argc, char** argv)
  36. {
  37. init_arrays();
  38. build_tree();
  39. /*** check emdb line coverage ***/
  40. check_coverage();
  41. print_tree(argv[1]);
  42. exit(0);
  43. }
  44. /***********************************************************************
  45. init_arrays - this function calculates the value of the
  46. extensions for each emdb line, that is, it creates a bit pattern which
  47. represents the encoding of the extensions of an emdb line.
  48. ***********************************************************************/
  49. FUNC void init_arrays()
  50. {
  51. U64 value, ext_val;
  52. int i, pos;
  53. Inst_id_t emdb_entry;
  54. Format_t format;
  55. /*** calculate emdb lines extensions ***/
  56. IEL_ZERO(emdb_ext_values[0]); /* illop */
  57. for (emdb_entry = EM_INST_NONE+1; emdb_entry < EM_INST_NONE+DEC_IGN_NUM_INST;
  58. emdb_entry++)
  59. {
  60. format = dec_ign_EMDB_info[emdb_entry].format;
  61. IEL_ZERO(value);
  62. for (i = 0; i < MAX_NUM_OF_EXT; i++)
  63. {
  64. pos = format_extensions[format][i].pos;
  65. IEL_CONVERT2(ext_val, dec_ign_EMDB_info[emdb_entry].extensions[i], 0);
  66. IEL_SHL(ext_val, ext_val, pos);
  67. IEL_OR(value, value, ext_val);
  68. }
  69. IEL_ASSIGNU(emdb_ext_values[emdb_entry], value);
  70. }
  71. /*** init cover_emdb_lines[] ***/
  72. for (emdb_entry = EM_INST_NONE+1; emdb_entry < EM_INST_NONE+DEC_IGN_NUM_INST;
  73. emdb_entry++)
  74. {
  75. cover_emdb_lines[emdb_entry] = 0;
  76. }
  77. }
  78. /***********************************************************************
  79. build_tree - builds the decision tree
  80. ***********************************************************************/
  81. FUNC void build_tree()
  82. {
  83. Square_t square;
  84. unsigned int cur_node = 0;
  85. next_free_node = cur_node + EM_SQUARE_LAST;
  86. for (square = EM_SQUARE_FIRST; square < EM_SQUARE_LAST; square++)
  87. {
  88. build_node(format_extension_masks,
  89. square_emdb_lines[square], cur_node);
  90. cur_node++;
  91. }
  92. }
  93. /***********************************************************************
  94. build_node - input: array extension bit masks of each format
  95. emdb lines list
  96. currrent node
  97. builds the current node, calls build_node recursively
  98. for each son.
  99. ***********************************************************************/
  100. FUNC void build_node(U64 *format_masks,
  101. Inst_id_list_t emdb_lines, unsigned int cur_node)
  102. {
  103. U64 emdb_values[MAX_EMDB_LINES];
  104. unsigned int i, j;
  105. U64 intersect, delete_bits;
  106. U64 intersect_mask = IEL_CONST64(0xffffffff, 0xffffffff);
  107. int pos, size, number_of_sons;
  108. unsigned int line_count;
  109. Format_t format;
  110. U64 new_format_masks[EM_FORMAT_LAST];
  111. Inst_id_list_t new_emdb_lines;
  112. /*** empty node - ILLOP ***/
  113. if (emdb_lines.num_of_lines == 0)
  114. {
  115. tree[cur_node].pos = tree[cur_node].size = -1;
  116. tree[cur_node].next_node = EM_ILLOP;
  117. return;
  118. }
  119. /*** one line in node - a single emdb entry ***/
  120. if (emdb_lines.num_of_lines == 1)
  121. {
  122. format = dec_ign_EMDB_info[emdb_lines.inst_ids[0]].format;
  123. if (IEL_ISZERO(format_masks[format]))
  124. {
  125. /* all extensions are cheked */
  126. tree[cur_node].pos = tree[cur_node].size = -1;
  127. tree[cur_node].next_node = dec_ign_EMDB_info[emdb_lines.inst_ids[0]].inst_id;
  128. cover_emdb_lines[tree[cur_node].next_node]++;
  129. return;
  130. }
  131. intersect_mask = format_masks[format];
  132. }
  133. else
  134. {
  135. /*** this line is reached when there are more than one emdb lines
  136. which participate in this node ***/
  137. /*** calculate intersecting extensions ***/
  138. for (i = 0; i < (unsigned int)emdb_lines.num_of_lines; i++)
  139. {
  140. format = dec_ign_EMDB_info[emdb_lines.inst_ids[i]].format;
  141. IEL_AND(intersect_mask, intersect_mask, format_masks[format]);
  142. }
  143. }
  144. find_largest_intersection(intersect_mask, &pos, &size);
  145. if (pos == -1) /*** no intersection found ***/
  146. {
  147. fprintf(stderr, "no intersection in node %d\n", cur_node);
  148. exit(1);
  149. }
  150. /*** delete intersect mask bits from participating formats ***/
  151. for (i = EM_FORMAT_NONE; i < EM_FORMAT_LAST; i++)
  152. {
  153. IEL_ASSIGNU(new_format_masks[i], format_masks[i]);
  154. }
  155. /*** intersect = ((1 << size) -1) << pos; ***/
  156. IEL_SHL(intersect, ONE64, size);
  157. IEL_DECU(intersect);
  158. IEL_SHL(intersect, intersect, pos);
  159. IEL_NOT(delete_bits, intersect);
  160. for (i = 0; i < (unsigned int)emdb_lines.num_of_lines; i++)
  161. {
  162. format = dec_ign_EMDB_info[emdb_lines.inst_ids[i]].format;
  163. IEL_AND(new_format_masks[format], delete_bits, format_masks[format]);
  164. }
  165. /*** calculate values of participating emdb lines in intersection bits ***/
  166. build_emdb_values(emdb_values, emdb_lines, intersect, pos, size);
  167. /*** update current node ***/
  168. tree[cur_node].next_node = next_free_node;
  169. tree[cur_node].pos = pos;
  170. tree[cur_node].size = size;
  171. cur_node = next_free_node;
  172. if (next_free_node >= MAX_NODES)
  173. {
  174. fprintf (stderr, "tree is larger than %d\n", MAX_NODES);
  175. exit(1);
  176. }
  177. number_of_sons = (int)pow((double)2, (double)size);
  178. next_free_node += number_of_sons;
  179. /*** loop on each of the node's sons, build the tree recursively ***/
  180. for (i = 0; i < (unsigned int)number_of_sons; i++)
  181. {
  182. line_count = 0;
  183. new_emdb_lines.num_of_lines = 0;
  184. for (j = 0; j < (unsigned int)emdb_lines.num_of_lines; j++)
  185. {
  186. if (IEL_GETDW0(emdb_values[j]) == i && (!IEL_GETDW1(emdb_values[j])))
  187. /*** emdb line has the value i ***/
  188. {
  189. new_emdb_lines.num_of_lines++;
  190. new_emdb_lines.inst_ids[line_count++] = emdb_lines.inst_ids[j];
  191. }
  192. }
  193. build_node(new_format_masks, new_emdb_lines, cur_node);
  194. cur_node++;
  195. }
  196. }
  197. /***********************************************************************
  198. build_emdb_values - input: - pointer to an array into which
  199. calculated values of extensions
  200. will be written.
  201. - emdb lines list
  202. - bit pattern in which to calculate values
  203. - pos - start bit of pattern
  204. calculates values of emdb lines in all bits which
  205. are set in pattern
  206. ***********************************************************************/
  207. FUNC void build_emdb_values(U64 *emdb_values,
  208. Inst_id_list_t emdb_lines,
  209. U64 pattern,
  210. int pos, int size)
  211. {
  212. int i;
  213. U64 value;
  214. /* Format_t format;
  215. int j;
  216. char match;
  217. int new_pos, new_size;
  218. */
  219. for (i = 0; i < emdb_lines.num_of_lines; i++)
  220. {
  221. IEL_ASSIGNU(value, emdb_ext_values[emdb_lines.inst_ids[i]]);
  222. /*** emdb_values[i] = (value & pattern) >> pos; ***/
  223. IEL_AND(emdb_values[i], value, pattern);
  224. IEL_SHR(emdb_values[i], emdb_values[i], pos);
  225. /* format = dec_ign_EMDB_info[emdb_lines.inst_ids[i]].format;
  226. new_pos = pos+START_BIT;
  227. new_size = size;
  228. match = 0;
  229. for (j = MAX_NUM_OF_EXT-1; j >= 0; j--)
  230. {
  231. if (format_extensions[format][j].pos == new_pos)
  232. {
  233. if (format_extensions[format][j].size == new_size)
  234. {
  235. match = 1;
  236. }
  237. else if (format_extensions[format][j].size > new_size)
  238. {
  239. fprintf(stderr,
  240. "the intersection of emdb line %d is not full\n",
  241. emdb_lines.inst_ids[i]);
  242. exit(1);
  243. }
  244. else
  245. {
  246. new_pos += format_extensions[format][j].size;
  247. new_size -= format_extensions[format][j].size;
  248. }
  249. }
  250. }
  251. if (!match)
  252. {
  253. fprintf(stderr,
  254. "the intersection of emdb line %d is not full\n",
  255. emdb_lines.inst_ids[i]);
  256. exit(1);
  257. }
  258. */
  259. }
  260. }
  261. /***********************************************************************
  262. find_largest_intersection - fast algorithm for finding largest group of
  263. consecutive set bits in pattern.
  264. (Yigal's algorithm)
  265. ***********************************************************************/
  266. FUNC void find_largest_intersection(U64 pattern, int *pos, int *size)
  267. {
  268. U64 x;
  269. U64 y, z, u;
  270. IEL_ASSIGNU(x, pattern);
  271. *size = 0; /* largest intersection counter */
  272. IEL_SHR(y, x, 1);
  273. IEL_NOT(z, x); /* negation of the input pattern */
  274. IEL_OR(y, y, z); /* y - mask */
  275. while (!IEL_ISZERO(x))
  276. {
  277. IEL_ASSIGNU(u, x); /* for saving the last bit pattern */
  278. IEL_AND(x, x, y);
  279. IEL_SHR(y, y, 1); /* shift right mask */
  280. (*size)++;
  281. }
  282. /* inspect the high word for left most 1 */
  283. if (IEL_GETDW1(u) & 0xffe00000) /* something in bits 21-31 */
  284. {
  285. *pos = 21 + LOG2[IEL_GETDW1(u) >> 21] + 32;
  286. }
  287. else if (IEL_GETDW1(u) & 0x1ffc00) /* something in bits 10-20 */
  288. {
  289. *pos = 10 + LOG2[IEL_GETDW1(u) >> 10] + 32;
  290. }
  291. else if (IEL_GETDW1(u))
  292. {
  293. *pos = LOG2[IEL_GETDW1(u)] + 32;
  294. }
  295. /* inspect the low word for left most 1 */
  296. else if (IEL_GETDW0(u) & 0xffe00000) /* something in bits 21-31 */
  297. {
  298. *pos = 21 + LOG2[IEL_GETDW0(u) >> 21];
  299. }
  300. else if (IEL_GETDW0(u) & 0x1ffc00) /* something in bits 10-20 */
  301. {
  302. *pos = 10 + LOG2[IEL_GETDW0(u) >> 10];
  303. }
  304. else
  305. {
  306. *pos = LOG2[IEL_GETDW0(u)];
  307. }
  308. }
  309. /***********************************************************************
  310. check_coverage - check coverage of emdb lines in the tree
  311. ***********************************************************************/
  312. FUNC void check_coverage()
  313. {
  314. Inst_id_t emdb_entry;
  315. for (emdb_entry = EM_INST_NONE+1; emdb_entry < DECCPU_NUM_INST; emdb_entry++)
  316. {
  317. if (cover_emdb_lines[emdb_entry] < 1)
  318. {
  319. fprintf(stderr, "%d doesn't appear in the tree\n",
  320. emdb_entry);
  321. }
  322. }
  323. }
  324. /***********************************************************************
  325. print_tree - prints the initialized em_decision_tree in decision_tree.c
  326. ***********************************************************************/
  327. FUNC void print_tree(char* file)
  328. {
  329. FILE *fd;
  330. int i;
  331. if ((fd = fopen(file, "w")) == NULL)
  332. {
  333. fprintf(stderr, "Couldn't open decision_tree.c\n");
  334. exit(1);
  335. }
  336. fprintf(fd, "/*** decision_tree.c ***/\n\n#include \"decision_tree.h\"\n\n");
  337. fprintf(fd, "Node_t em_decision_tree[] = {\n");
  338. /*** traverse the tree ***/
  339. for (i = 0; i < (int)next_free_node; i++)
  340. {
  341. fprintf(fd, "/*%05d*/ {%d, %d, %d}", i, tree[i].next_node,
  342. tree[i].pos, tree[i].size);
  343. if (i != (int)next_free_node-1)
  344. {
  345. fprintf(fd, ",");
  346. }
  347. fprintf(fd, "\n");
  348. }
  349. fprintf(fd, "};\n");
  350. }