PageRenderTime 58ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/opengles/src/codegen/instruction.c

http://ftk.googlecode.com/
C | 2091 lines | 1544 code | 445 blank | 102 comment | 237 complexity | badf588d200dee8f4004d79840481a17 MD5 | raw file
Possible License(s): LGPL-3.0
  1. /****************************************************************************/
  2. /* */
  3. /* Copyright (c) 2004, Hans-Martin Will. All rights reserved. */
  4. /* */
  5. /* Redistribution and use in source and binary forms, with or without */
  6. /* modification, are permitted provided that the following conditions are */
  7. /* met: */
  8. /* */
  9. /* * Redistributions of source code must retain the above copyright */
  10. /* notice, this list of conditions and the following disclaimer. */
  11. /* */
  12. /* * Redistributions in binary form must reproduce the above copyright */
  13. /* notice, this list of conditions and the following disclaimer in the */
  14. /* documentation and/or other materials provided with the distribution. */
  15. /* */
  16. /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
  17. /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
  18. /* LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A */
  19. /* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER */
  20. /* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */
  21. /* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, */
  22. /* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR */
  23. /* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
  24. /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
  25. /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
  26. /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
  27. /* */
  28. /****************************************************************************/
  29. #include <stdarg.h>
  30. #include "instruction.h"
  31. #include "bitset.h"
  32. #include "arm-codegen.h"
  33. static cg_virtual_reg_t ** add_reg(cg_virtual_reg_t * reg,
  34. cg_virtual_reg_t ** dest,
  35. cg_virtual_reg_t * const * limit)
  36. {
  37. if (dest != limit)
  38. *dest++ = reg;
  39. return dest;
  40. }
  41. static cg_virtual_reg_t ** add_reg_list(cg_virtual_reg_list_t * list,
  42. cg_virtual_reg_t ** dest,
  43. cg_virtual_reg_t * const * limit)
  44. {
  45. while (list)
  46. {
  47. dest = add_reg(list->reg, dest, limit);
  48. list = list->next;
  49. }
  50. return dest;
  51. }
  52. static void add_interference(cg_heap_t * heap, cg_virtual_reg_t * source, cg_virtual_reg_t * target)
  53. {
  54. cg_virtual_reg_list_t ** iter;
  55. cg_virtual_reg_list_t * node;
  56. source = source->representative;
  57. target = target->representative;
  58. if (source == target)
  59. return;
  60. for (iter = &source->interferences; *iter; iter = &(*iter)->next)
  61. {
  62. if ((*iter)->reg == target)
  63. return;
  64. }
  65. node = (cg_virtual_reg_list_t *) cg_heap_allocate(heap, sizeof(cg_virtual_reg_list_t));
  66. node->next = NULL;
  67. node->reg = target;
  68. *iter = node;
  69. }
  70. /****************************************************************************/
  71. /* Determine the set of defined registers for the instruction passed in. */
  72. /* dest points to a buffer into which the result will be stored, limit */
  73. /* specifies an upper limit on this buffer. The return value will be */
  74. /* pointing right after the last register stored in the destanation area. */
  75. /****************************************************************************/
  76. cg_virtual_reg_t ** cg_inst_def(const cg_inst_t * inst,
  77. cg_virtual_reg_t ** dest,
  78. cg_virtual_reg_t * const * limit)
  79. {
  80. switch (inst->base.kind)
  81. {
  82. case cg_inst_unary:
  83. case cg_inst_arm_unary_immed:
  84. case cg_inst_arm_unary_shift_reg:
  85. case cg_inst_arm_unary_shift_immed:
  86. dest = add_reg(inst->unary.dest_value, dest, limit);
  87. if (inst->unary.dest_flags)
  88. dest = add_reg(inst->unary.dest_flags, dest, limit);
  89. return dest;
  90. case cg_inst_binary:
  91. case cg_inst_arm_binary_immed:
  92. case cg_inst_arm_binary_shift_reg:
  93. case cg_inst_arm_binary_shift_immed:
  94. dest = add_reg(inst->binary.dest_value, dest, limit);
  95. if (inst->binary.dest_flags)
  96. dest = add_reg(inst->binary.dest_flags, dest, limit);
  97. return dest;
  98. case cg_inst_compare:
  99. case cg_inst_arm_compare_immed:
  100. case cg_inst_arm_compare_shift_reg:
  101. case cg_inst_arm_compare_shift_immed:
  102. return add_reg(inst->compare.dest_flags, dest, limit);
  103. default:
  104. ;
  105. }
  106. switch (inst->base.kind)
  107. {
  108. case cg_inst_load:
  109. case cg_inst_arm_load_immed_offset:
  110. case cg_inst_arm_load_reg_offset:
  111. return add_reg(inst->load.dest, dest, limit);
  112. case cg_inst_store:
  113. case cg_inst_arm_store_immed_offset:
  114. case cg_inst_arm_store_reg_offset:
  115. return dest;
  116. case cg_inst_load_immed:
  117. return add_reg(inst->immed.dest, dest, limit);
  118. case cg_inst_branch_label:
  119. case cg_inst_branch_cond:
  120. return dest;
  121. case cg_inst_phi:
  122. return add_reg(inst->phi.dest, dest, limit);
  123. case cg_inst_call:
  124. if (inst->call.dest)
  125. return add_reg(inst->call.dest, dest, limit);
  126. else
  127. return dest;
  128. case cg_inst_ret:
  129. return dest;
  130. // ARM specific formats
  131. default:
  132. assert(0);
  133. }
  134. return dest;
  135. }
  136. /****************************************************************************/
  137. /* Determine the set of used registers for the instruction passed in. */
  138. /* dest points to a buffer into which the result will be stored, limit */
  139. /* specifies an upper limit on this buffer. The return value will be */
  140. /* pointing right after the last register stored in the destanation area. */
  141. /****************************************************************************/
  142. cg_virtual_reg_t ** cg_inst_use(const cg_inst_t * inst,
  143. cg_virtual_reg_t ** dest,
  144. cg_virtual_reg_t * const * limit)
  145. {
  146. switch (inst->base.kind)
  147. {
  148. case cg_inst_unary:
  149. return add_reg(inst->unary.operand.source, dest, limit);
  150. case cg_inst_arm_unary_immed:
  151. return dest;
  152. case cg_inst_arm_unary_shift_reg:
  153. dest = add_reg(inst->unary.operand.shift_reg.source, dest, limit);
  154. return add_reg(inst->unary.operand.shift_reg.shift, dest, limit);
  155. case cg_inst_arm_unary_shift_immed:
  156. return add_reg(inst->unary.operand.shift_immed.source, dest, limit);
  157. case cg_inst_binary:
  158. dest = add_reg(inst->binary.source, dest, limit);
  159. return add_reg(inst->binary.operand.source, dest, limit);
  160. case cg_inst_arm_binary_immed:
  161. return add_reg(inst->binary.source, dest, limit);
  162. case cg_inst_arm_binary_shift_reg:
  163. dest = add_reg(inst->binary.source, dest, limit);
  164. dest = add_reg(inst->binary.operand.shift_reg.source, dest, limit);
  165. return add_reg(inst->binary.operand.shift_reg.shift, dest, limit);
  166. case cg_inst_arm_binary_shift_immed:
  167. dest = add_reg(inst->binary.source, dest, limit);
  168. return add_reg(inst->binary.operand.shift_immed.source, dest, limit);
  169. case cg_inst_compare:
  170. dest = add_reg(inst->compare.source, dest, limit);
  171. return add_reg(inst->compare.operand.source, dest, limit);
  172. case cg_inst_arm_compare_immed:
  173. return add_reg(inst->compare.source, dest, limit);
  174. case cg_inst_arm_compare_shift_reg:
  175. dest = add_reg(inst->compare.source, dest, limit);
  176. dest = add_reg(inst->compare.operand.shift_reg.source, dest, limit);
  177. return add_reg(inst->compare.operand.shift_reg.shift, dest, limit);
  178. case cg_inst_arm_compare_shift_immed:
  179. dest = add_reg(inst->compare.source, dest, limit);
  180. return add_reg(inst->compare.operand.shift_immed.source, dest, limit);
  181. case cg_inst_load:
  182. return add_reg(inst->load.mem.base, dest, limit);
  183. case cg_inst_arm_load_immed_offset:
  184. return add_reg(inst->load.mem.immed_offset.base, dest, limit);
  185. case cg_inst_arm_load_reg_offset:
  186. dest = add_reg(inst->load.mem.reg_offset.base, dest, limit);
  187. return add_reg(inst->load.mem.reg_offset.offset, dest, limit);
  188. case cg_inst_store:
  189. dest = add_reg(inst->store.source, dest, limit);
  190. return add_reg(inst->store.mem.base, dest, limit);
  191. case cg_inst_arm_store_immed_offset:
  192. dest = add_reg(inst->store.source, dest, limit);
  193. return add_reg(inst->store.mem.immed_offset.base, dest, limit);
  194. case cg_inst_arm_store_reg_offset:
  195. dest = add_reg(inst->store.source, dest, limit);
  196. dest = add_reg(inst->store.mem.reg_offset.base, dest, limit);
  197. return add_reg(inst->store.mem.reg_offset.offset, dest, limit);
  198. case cg_inst_load_immed:
  199. return dest;
  200. case cg_inst_branch_label:
  201. return dest;
  202. case cg_inst_branch_cond:
  203. return add_reg(inst->branch.cond, dest, limit);
  204. case cg_inst_phi:
  205. return add_reg_list(inst->phi.regs, dest, limit);
  206. case cg_inst_call:
  207. return add_reg_list(inst->call.args, dest, limit);
  208. case cg_inst_ret:
  209. if (inst->ret.result)
  210. return add_reg(inst->ret.result, dest, limit);
  211. else
  212. return dest;
  213. // ARM specific formats
  214. default:
  215. assert(0);
  216. }
  217. return dest;
  218. }
  219. void mark_instruction_used(cg_inst_t * inst)
  220. {
  221. cg_virtual_reg_t * buffer[16];
  222. cg_virtual_reg_t **iter, ** end;
  223. if (inst->base.used)
  224. return;
  225. inst->base.used = 1;
  226. end = cg_inst_use(inst, buffer, buffer + 16);
  227. for (iter = buffer; iter != end; ++iter)
  228. {
  229. cg_virtual_reg_t * reg = *iter;
  230. if (reg->def && !reg->def->base.used)
  231. mark_instruction_used(reg->def);
  232. }
  233. }
  234. void cg_module_eliminate_dead_code(cg_module_t * module)
  235. {
  236. cg_proc_t * proc;
  237. cg_block_t * block;
  238. cg_inst_t * inst, ** pinst;
  239. /************************************************************************/
  240. /* Mark all instructions as unused */
  241. /************************************************************************/
  242. for (proc = module->procs; proc; proc = proc->next)
  243. {
  244. for (block = proc->blocks; block; block = block->next)
  245. {
  246. for (inst = block->insts.head; inst; inst = inst->base.next)
  247. {
  248. inst->base.used = 0;
  249. }
  250. }
  251. }
  252. /************************************************************************/
  253. /* mark used instructions */
  254. /************************************************************************/
  255. for (proc = module->procs; proc; proc = proc->next)
  256. {
  257. for (block = proc->blocks; block; block = block->next)
  258. {
  259. for (inst = block->insts.head; inst; inst = inst->base.next)
  260. {
  261. if (inst->base.kind == cg_inst_store ||
  262. inst->base.kind == cg_inst_arm_store_immed_offset ||
  263. inst->base.kind == cg_inst_arm_store_reg_offset ||
  264. inst->base.kind == cg_inst_ret ||
  265. inst->base.kind == cg_inst_call ||
  266. inst->base.kind == cg_inst_branch_cond ||
  267. inst->base.kind == cg_inst_branch_label)
  268. {
  269. mark_instruction_used(inst);
  270. }
  271. }
  272. }
  273. }
  274. /************************************************************************/
  275. /* remove un-used instructions */
  276. /************************************************************************/
  277. for (proc = module->procs; proc; proc = proc->next)
  278. {
  279. for (block = proc->blocks; block; block = block->next)
  280. {
  281. for (pinst = &block->insts.head; *pinst; )
  282. {
  283. if ((*pinst)->base.used)
  284. {
  285. pinst = &(*pinst)->base.next;
  286. }
  287. else
  288. {
  289. *pinst = (*pinst)->base.next;
  290. }
  291. }
  292. }
  293. }
  294. }
  295. static void block_dataflow(cg_block_t * block)
  296. {
  297. cg_inst_t * inst;
  298. block->def = cg_bitset_create(block->proc->module->heap, block->proc->num_registers);
  299. block->use = cg_bitset_create(block->proc->module->heap, block->proc->num_registers);
  300. block->live_in = cg_bitset_create(block->proc->module->heap, block->proc->num_registers);
  301. block->live_out = cg_bitset_create(block->proc->module->heap, block->proc->num_registers);
  302. for (inst = block->insts.head; inst; inst = inst->base.next)
  303. {
  304. cg_virtual_reg_t * buffer[64];
  305. cg_virtual_reg_t **iter, ** end = cg_inst_use(inst, buffer, buffer + 64);
  306. for (iter = buffer; iter != end; ++iter)
  307. {
  308. cg_virtual_reg_t * use = *iter;
  309. if (!CG_BITSET_TEST(block->def, use->reg_no))
  310. {
  311. /* if the register has not been defined yet it means we received it as */
  312. /* input to the block */
  313. CG_BITSET_SET(block->use, use->reg_no);
  314. }
  315. }
  316. end = cg_inst_def(inst, buffer, buffer + 64);
  317. for (iter = buffer; iter != end; ++iter)
  318. {
  319. cg_virtual_reg_t * def = *iter;
  320. CG_BITSET_SET(block->def, def->reg_no);
  321. }
  322. }
  323. cg_bitset_assign(block->live_in, block->use);
  324. }
  325. static void proc_dataflow(cg_proc_t * proc)
  326. {
  327. int changed;
  328. cg_block_t * block;
  329. cg_block_list_t * list;
  330. // for each block establish def and use sets
  331. for (block = proc->blocks; block; block = block->next)
  332. block_dataflow(block);
  333. // repeat until no further change:
  334. // live_out(b) := U live_in(b), b in succ(b)
  335. // live_in(b) := live_in(b) U (live_out(b) \ def(b))
  336. do
  337. {
  338. changed = 0;
  339. for (block = proc->blocks; block; block = block->next)
  340. {
  341. for (list = block->succ; list; list = list->next)
  342. changed |= cg_bitset_union(block->live_out, list->block->live_in);
  343. changed |= cg_bitset_union_minus(block->live_in, block->live_out, block->def);
  344. }
  345. }
  346. while (changed);
  347. }
  348. static void add_successor(cg_block_t * block, cg_block_t * succ)
  349. {
  350. cg_block_list_t * list = cg_heap_allocate(block->proc->module->heap, sizeof(cg_block_list_t));
  351. list->block = succ;
  352. list->next = block->succ;
  353. block->succ = list;
  354. }
  355. static void add_predecessor(cg_block_t * block, cg_block_t * pred)
  356. {
  357. cg_block_list_t * list = cg_heap_allocate(block->proc->module->heap, sizeof(cg_block_list_t));
  358. list->block = pred;
  359. list->next = block->pred;
  360. block->pred = list;
  361. }
  362. static void proc_controlflow(cg_proc_t * proc)
  363. {
  364. // for each block determine list of preedecessor and successor blocks
  365. cg_block_t * block;
  366. cg_inst_t * inst;
  367. for (block = proc->blocks; block; block = block->next)
  368. {
  369. int last_inst_is_bra = 0;
  370. for (inst = block->insts.head; inst; inst = inst->base.next)
  371. {
  372. if (inst->base.kind == cg_inst_branch_cond ||
  373. inst->base.kind == cg_inst_branch_label)
  374. {
  375. cg_block_t * target = inst->branch.target->block;
  376. add_successor(block, target);
  377. add_predecessor(target, block);
  378. }
  379. last_inst_is_bra = inst->base.opcode == cg_op_bra;
  380. }
  381. if (!last_inst_is_bra && block->next)
  382. {
  383. add_successor(block, block->next);
  384. add_predecessor(block->next, block);
  385. }
  386. }
  387. }
  388. void cg_module_dataflow(cg_module_t * module)
  389. {
  390. // perform def/use and liveliness analysis
  391. cg_proc_t * proc;
  392. for (proc = module->procs; proc != (cg_proc_t *) 0; proc = proc->next)
  393. {
  394. proc_controlflow(proc);
  395. proc_dataflow(proc);
  396. }
  397. }
  398. static int is_arm_unary_data_opcode(cg_opcode_t opcode) {
  399. switch (opcode) {
  400. case cg_op_not:
  401. return 1;
  402. default:
  403. return 0;
  404. }
  405. }
  406. static int is_arm_binary_data_opcode(cg_opcode_t opcode) {
  407. switch (opcode) {
  408. case cg_op_add:
  409. case cg_op_and:
  410. case cg_op_or:
  411. case cg_op_sub:
  412. case cg_op_xor:
  413. case cg_op_fadd:
  414. case cg_op_fsub:
  415. case cg_op_min:
  416. case cg_op_max:
  417. return 1;
  418. default:
  419. return 0;
  420. }
  421. }
  422. static int is_shift_or_rotate(cg_opcode_t opcode) {
  423. switch (opcode) {
  424. case cg_op_asr:
  425. case cg_op_lsr:
  426. case cg_op_lsl:
  427. return 1;
  428. default:
  429. return 0;
  430. }
  431. }
  432. static int is_arm_data_proc_immediate(U32 value) {
  433. // preliminary rule
  434. int shift;
  435. if ((value & 0xff) == value) {
  436. return 1;
  437. }
  438. for (shift = 2; shift <= 12; shift += 2) {
  439. if (((0xff << shift) & value) == value)
  440. return 1;
  441. }
  442. return 0;
  443. }
  444. typedef enum
  445. {
  446. amode_register,
  447. amode_immed,
  448. amode_shift_immed,
  449. amode_shift_reg
  450. }
  451. amode_t;
  452. typedef enum
  453. {
  454. dmode_register,
  455. dmode_immed_offset,
  456. dmode_reg_offset
  457. }
  458. dmode_t;
  459. static amode_t consolidate_amode(cg_data_operand_t * operand)
  460. {
  461. cg_inst_t * source_inst;
  462. if (!operand->source->def)
  463. return amode_register;
  464. source_inst = operand->source->def;
  465. switch (source_inst->base.kind)
  466. {
  467. case cg_inst_load_immed:
  468. // constant
  469. {
  470. if (is_arm_const(source_inst->immed.value))
  471. {
  472. operand->immed = source_inst->immed.value;
  473. return amode_immed;
  474. }
  475. }
  476. break;
  477. case cg_inst_binary:
  478. // check for general shift -> shift reg
  479. {
  480. switch (source_inst->base.opcode)
  481. {
  482. case cg_op_asr:
  483. operand->shift_reg.source = source_inst->binary.source;
  484. operand->shift_reg.op = cg_shift_asr;
  485. operand->shift_reg.shift = source_inst->binary.operand.source;
  486. return amode_shift_reg;
  487. case cg_op_lsr:
  488. operand->shift_reg.source = source_inst->binary.source;
  489. operand->shift_reg.op = cg_shift_lsr;
  490. operand->shift_reg.shift = source_inst->binary.operand.source;
  491. return amode_shift_reg;
  492. case cg_op_lsl:
  493. operand->shift_reg.source = source_inst->binary.source;
  494. operand->shift_reg.op = cg_shift_lsl;
  495. operand->shift_reg.shift = source_inst->binary.operand.source;
  496. return amode_shift_reg;
  497. }
  498. }
  499. break;
  500. case cg_inst_arm_binary_immed:
  501. // maybe we already consolidated the shift -> shift immed
  502. {
  503. switch (source_inst->base.opcode)
  504. {
  505. case cg_op_asr:
  506. operand->shift_immed.source = source_inst->binary.source;
  507. operand->shift_immed.op = cg_shift_asr;
  508. operand->shift_immed.shift = source_inst->binary.operand.immed;
  509. return amode_shift_immed;
  510. case cg_op_lsr:
  511. operand->shift_immed.source = source_inst->binary.source;
  512. operand->shift_immed.op = cg_shift_lsr;
  513. operand->shift_immed.shift = source_inst->binary.operand.immed;
  514. return amode_shift_immed;
  515. case cg_op_lsl:
  516. operand->shift_immed.source = source_inst->binary.source;
  517. operand->shift_immed.op = cg_shift_lsl;
  518. operand->shift_immed.shift = source_inst->binary.operand.immed;
  519. return amode_shift_immed;
  520. }
  521. }
  522. break;
  523. default:
  524. break;
  525. }
  526. return amode_register;
  527. }
  528. static dmode_t consolidate_dmode(cg_mem_operand_t * operand)
  529. {
  530. cg_inst_t * source_inst = operand->base->def;
  531. if (!source_inst)
  532. return dmode_register;
  533. if (source_inst->base.opcode == cg_op_add &&
  534. source_inst->base.kind == cg_inst_binary)
  535. {
  536. operand->reg_offset.base = source_inst->binary.source;
  537. operand->reg_offset.offset = source_inst->binary.operand.source;
  538. return dmode_reg_offset;
  539. }
  540. else if (source_inst->base.opcode == cg_op_add &&
  541. source_inst->base.kind == cg_inst_arm_binary_immed &&
  542. source_inst->binary.operand.immed >= 0 &&
  543. source_inst->binary.operand.immed <= 0xff)
  544. {
  545. operand->immed_offset.base = source_inst->binary.source;
  546. operand->immed_offset.offset = source_inst->binary.operand.immed;
  547. return dmode_immed_offset;
  548. }
  549. return dmode_register;
  550. }
  551. static void inst_amode(cg_inst_t * inst)
  552. {
  553. switch (inst->base.kind)
  554. {
  555. case cg_inst_unary:
  556. if (is_arm_unary_data_opcode(inst->base.opcode))
  557. {
  558. amode_t amode = consolidate_amode(&inst->unary.operand);
  559. switch (amode)
  560. {
  561. case amode_immed:
  562. inst->base.kind = cg_inst_arm_unary_immed;
  563. break;
  564. case amode_shift_immed:
  565. inst->base.kind = cg_inst_arm_unary_shift_immed;
  566. break;
  567. case amode_shift_reg:
  568. inst->base.kind = cg_inst_arm_unary_shift_reg;
  569. break;
  570. default:
  571. break;
  572. }
  573. }
  574. break;
  575. case cg_inst_binary:
  576. if (is_arm_binary_data_opcode(inst->base.opcode))
  577. {
  578. amode_t amode = consolidate_amode(&inst->binary.operand);
  579. switch (amode)
  580. {
  581. case amode_immed:
  582. inst->base.kind = cg_inst_arm_binary_immed;
  583. break;
  584. case amode_shift_immed:
  585. inst->base.kind = cg_inst_arm_binary_shift_immed;
  586. break;
  587. case amode_shift_reg:
  588. inst->base.kind = cg_inst_arm_binary_shift_reg;
  589. break;
  590. default:
  591. break;
  592. }
  593. }
  594. else switch (inst->base.opcode)
  595. {
  596. case cg_op_asr:
  597. case cg_op_lsr:
  598. case cg_op_lsl:
  599. {
  600. cg_inst_t * source_inst = inst->binary.operand.source->def;
  601. if (source_inst && source_inst->base.kind == cg_inst_load_immed)
  602. {
  603. inst->binary.operand.immed = source_inst->immed.value;
  604. inst->base.kind = cg_inst_arm_binary_immed;
  605. }
  606. }
  607. break;
  608. }
  609. break;
  610. case cg_inst_compare:
  611. {
  612. amode_t amode = consolidate_amode(&inst->compare.operand);
  613. switch (amode)
  614. {
  615. case amode_immed:
  616. inst->base.kind = cg_inst_arm_compare_immed;
  617. break;
  618. case amode_shift_immed:
  619. inst->base.kind = cg_inst_arm_compare_shift_immed;
  620. break;
  621. case amode_shift_reg:
  622. inst->base.kind = cg_inst_arm_compare_shift_reg;
  623. break;
  624. default:
  625. break;
  626. }
  627. }
  628. break;
  629. case cg_inst_load:
  630. {
  631. dmode_t dmode = consolidate_dmode(&inst->load.mem);
  632. switch (dmode)
  633. {
  634. case dmode_reg_offset:
  635. inst->base.kind = cg_inst_arm_load_reg_offset;
  636. break;
  637. case dmode_immed_offset:
  638. inst->base.kind = cg_inst_arm_load_immed_offset;
  639. break;
  640. default:
  641. break;
  642. }
  643. }
  644. break;
  645. case cg_inst_store:
  646. {
  647. dmode_t dmode = consolidate_dmode(&inst->store.mem);
  648. switch (dmode)
  649. {
  650. case dmode_reg_offset:
  651. inst->base.kind = cg_inst_arm_store_reg_offset;
  652. break;
  653. case dmode_immed_offset:
  654. inst->base.kind = cg_inst_arm_store_immed_offset;
  655. break;
  656. default:
  657. break;
  658. }
  659. }
  660. break;
  661. default:
  662. break;
  663. }
  664. }
  665. void cg_module_amode(cg_module_t * module)
  666. {
  667. cg_proc_t * proc;
  668. cg_block_t * block;
  669. cg_inst_t * inst;
  670. for (proc = module->procs; proc; proc = proc->next)
  671. {
  672. for (block = proc->blocks; block; block = block->next)
  673. {
  674. for (inst = block->insts.head; inst; inst = inst->base.next)
  675. {
  676. inst_amode(inst);
  677. }
  678. }
  679. }
  680. }
  681. static void proc_allocate_variables(cg_proc_t * proc)
  682. {
  683. cg_virtual_reg_t * reg;
  684. size_t arg_count = proc->num_args;
  685. size_t arg_offset = 0;
  686. proc->num_registers = 0;
  687. proc->local_storage = 0;
  688. for (reg = proc->registers; reg; reg = reg->next)
  689. {
  690. reg->fp_offset = ~0;
  691. reg->reg_no = ~0;
  692. }
  693. for (reg = proc->registers; reg && arg_count; reg = reg->next, arg_count--)
  694. {
  695. reg->reg_no = reg->representative->reg_no = proc->num_registers++;
  696. reg->fp_offset = reg->representative->fp_offset = arg_offset;
  697. arg_offset += sizeof(U32);
  698. }
  699. for (; reg ; reg = reg->next)
  700. {
  701. if (reg->representative->reg_no == ~0)
  702. {
  703. reg->representative->reg_no = proc->num_registers++;
  704. }
  705. reg->reg_no = reg->representative->reg_no;
  706. }
  707. }
  708. void cg_module_allocate_variables(cg_module_t * module)
  709. {
  710. // allocate local variables in stack frame
  711. cg_proc_t * proc;
  712. cg_module_unify_registers(module);
  713. for (proc = module->procs; proc; proc = proc->next)
  714. proc_allocate_variables(proc);
  715. }
  716. static cg_virtual_reg_t * find_set(cg_virtual_reg_t * reg)
  717. {
  718. cg_virtual_reg_t * result;
  719. if (!reg->representative || reg->representative == reg)
  720. return reg;
  721. result = find_set(reg->representative);
  722. if (result != reg->representative)
  723. reg->representative = result;
  724. return result;
  725. }
  726. static void find_union(cg_virtual_reg_t * first, cg_virtual_reg_t * second)
  727. {
  728. cg_virtual_reg_t * first_set = find_set(first);
  729. cg_virtual_reg_t * second_set = find_set(second);
  730. second_set->representative = first_set;
  731. }
  732. void cg_module_unify_registers(cg_module_t * module)
  733. {
  734. cg_proc_t * proc;
  735. cg_block_t * block;
  736. cg_inst_t * inst;
  737. cg_virtual_reg_t * reg;
  738. for (proc = module->procs; proc; proc = proc->next)
  739. {
  740. /********************************************************************/
  741. /* Initialize all registers as being distinct */
  742. /********************************************************************/
  743. for (reg = proc->registers; reg; reg = reg->next)
  744. {
  745. reg->representative = reg;
  746. }
  747. /********************************************************************/
  748. /* Perform union-find for all registers that occur in a phi */
  749. /* instruction */
  750. /********************************************************************/
  751. for (block = proc->blocks; block; block = block->next)
  752. {
  753. cg_virtual_reg_list_t * list;
  754. for (inst = block->insts.head; inst && inst->base.opcode == cg_op_phi;
  755. inst = inst->base.next)
  756. {
  757. for (list = inst->phi.regs; list; list = list->next)
  758. {
  759. find_union(inst->phi.dest, list->reg);
  760. }
  761. }
  762. }
  763. /********************************************************************/
  764. /* Flatten out indirections so that there is at most one level of */
  765. /* indirection between any register and its representative */
  766. /********************************************************************/
  767. for (reg = proc->registers; reg; reg = reg->next)
  768. {
  769. find_set(reg);
  770. }
  771. }
  772. }
  773. static void proc_inst_def(cg_proc_t * proc)
  774. {
  775. cg_virtual_reg_t * reg;
  776. cg_block_t * block;
  777. cg_inst_t * inst;
  778. /************************************************************************/
  779. /* Clear out def and use information associated with virtual registers */
  780. /************************************************************************/
  781. for (reg = proc->registers; reg; reg = reg->next)
  782. {
  783. reg->def = (cg_inst_t *) 0;
  784. reg->use = (cg_inst_list_t *) 0;
  785. }
  786. /************************************************************************/
  787. /* Add def and use information for each register */
  788. /************************************************************************/
  789. for (block = proc->blocks; block; block = block->next)
  790. {
  791. for (inst = block->insts.head; inst; inst = inst->base.next)
  792. {
  793. cg_virtual_reg_t * buffer[64];
  794. cg_virtual_reg_t **iter, ** end = cg_inst_def(inst, buffer, buffer + 64);
  795. for (iter = buffer; iter != end; ++iter)
  796. {
  797. cg_virtual_reg_t * reg = *iter;
  798. assert(reg->def == (cg_inst_t *) 0);
  799. reg->def = inst;
  800. }
  801. }
  802. }
  803. }
  804. void cg_module_inst_def(cg_module_t * module)
  805. {
  806. cg_proc_t * proc;
  807. for (proc = module->procs; proc; proc = proc->next)
  808. proc_inst_def(proc);
  809. }
  810. static void proc_inst_use_chains(cg_proc_t * proc)
  811. {
  812. cg_virtual_reg_t * reg;
  813. cg_block_t * block;
  814. cg_inst_t * inst;
  815. /************************************************************************/
  816. /* Clear out def and use information associated with virtual registers */
  817. /************************************************************************/
  818. for (reg = proc->registers; reg; reg = reg->next)
  819. {
  820. reg->def = (cg_inst_t *) 0;
  821. reg->use = (cg_inst_list_t *) 0;
  822. }
  823. /************************************************************************/
  824. /* Add def qand use information for each register */
  825. /************************************************************************/
  826. for (block = proc->blocks; block; block = block->next)
  827. {
  828. for (inst = block->insts.head; inst; inst = inst->base.next)
  829. {
  830. cg_virtual_reg_t * buffer[64];
  831. cg_virtual_reg_t **iter, ** end = cg_inst_use(inst, buffer, buffer + 64);
  832. for (iter = buffer; iter != end; ++iter)
  833. {
  834. cg_virtual_reg_t * reg = *iter;
  835. cg_inst_list_t * list = cg_heap_allocate(proc->module->heap, sizeof(cg_inst_list_t));
  836. list->inst = inst;
  837. list->next = reg->use;
  838. reg->use = list;
  839. }
  840. }
  841. }
  842. }
  843. void cg_module_inst_use_chains(cg_module_t * module)
  844. {
  845. cg_proc_t * proc;
  846. for (proc = module->procs; proc; proc = proc->next)
  847. proc_inst_use_chains(proc);
  848. }
  849. /****************************************************************************/
  850. cg_module_t * cg_module_create(cg_heap_t * heap)
  851. {
  852. cg_module_t * module = cg_heap_allocate(heap, sizeof(cg_module_t));
  853. module->heap = heap;
  854. return module;
  855. }
  856. cg_proc_t * cg_proc_create(cg_module_t * module)
  857. {
  858. cg_proc_t * proc = cg_heap_allocate(module->heap, sizeof (cg_proc_t));
  859. proc->next = module->procs;
  860. module->procs = proc;
  861. proc->module = module;
  862. return proc;
  863. }
  864. cg_block_t * cg_block_create(cg_proc_t * proc, int weight)
  865. {
  866. cg_block_t * block = cg_heap_allocate(proc->module->heap, sizeof (cg_block_t));
  867. if (proc->blocks)
  868. {
  869. proc->last_block->next = block;
  870. proc->last_block = block;
  871. }
  872. else
  873. {
  874. proc->blocks = proc->last_block = block;
  875. }
  876. block->proc = proc;
  877. block->weight = weight;
  878. return block;
  879. }
  880. cg_virtual_reg_t * cg_virtual_reg_create(cg_proc_t * proc, cg_reg_type_t type)
  881. {
  882. cg_virtual_reg_t * reg = cg_heap_allocate(proc->module->heap, sizeof (cg_virtual_reg_t));
  883. reg->reg_no = proc->num_registers++;
  884. reg->type = type;
  885. if (proc->registers)
  886. {
  887. proc->last_register->next = reg;
  888. proc->last_register = reg;
  889. }
  890. else
  891. {
  892. proc->registers = proc->last_register = reg;
  893. }
  894. return reg;
  895. }
  896. cg_virtual_reg_list_t * cg_create_virtual_reg_list(cg_heap_t * heap, ...)
  897. {
  898. va_list marker;
  899. cg_virtual_reg_list_t * result = NULL, ** current = &result;
  900. va_start(marker, heap); /* Initialize variable arguments. */
  901. do
  902. {
  903. cg_virtual_reg_t * reg = va_arg(marker, cg_virtual_reg_t *);
  904. if (!reg)
  905. break;
  906. *current = cg_heap_allocate(heap, sizeof(cg_virtual_reg_list_t));
  907. (*current)->reg = reg;
  908. current = &(*current)->next;
  909. }
  910. while (1);
  911. va_end(marker); /* Reset variable arguments. */
  912. return result;
  913. }
  914. // add an instruction to a block
  915. static void block_add(cg_block_t * block, cg_inst_t * inst)
  916. {
  917. inst->base.block = block;
  918. if (block->insts.head)
  919. {
  920. block->insts.tail->base.next = inst;
  921. block->insts.tail = inst;
  922. }
  923. else
  924. {
  925. block->insts.head = block->insts.tail = inst;
  926. }
  927. }
  928. static cg_inst_t * inst_create(cg_block_t * block, size_t size,
  929. cg_inst_kind_t kind, cg_opcode_t op
  930. CG_INST_DEBUG_ARG_DECL)
  931. {
  932. cg_inst_t * inst = (cg_inst_t *)
  933. cg_heap_allocate(block->proc->module->heap, size);
  934. block_add(block, inst);
  935. inst->base.kind = kind;
  936. inst->base.opcode = op;
  937. CG_INST_SET_DEBUG(inst);
  938. return inst;
  939. }
  940. cg_inst_t * cg_create_inst_unary(cg_block_t * block,
  941. cg_opcode_t op,
  942. cg_virtual_reg_t * dest,
  943. cg_virtual_reg_t * source
  944. CG_INST_DEBUG_ARG_DECL)
  945. {
  946. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_unary_t), cg_inst_unary, op CG_INST_DEBUG_PASS);
  947. assert(dest->type == cg_reg_type_general);
  948. assert(source->type == cg_reg_type_general);
  949. inst->unary.dest_value = dest;
  950. inst->unary.operand.source = source;
  951. return inst;
  952. }
  953. cg_inst_t * cg_create_inst_unary_s(cg_block_t * block,
  954. cg_opcode_t op,
  955. cg_virtual_reg_t * dest,
  956. cg_virtual_reg_t * flags,
  957. cg_virtual_reg_t * source
  958. CG_INST_DEBUG_ARG_DECL)
  959. {
  960. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_unary_t), cg_inst_unary, op CG_INST_DEBUG_PASS);
  961. assert(dest->type == cg_reg_type_general);
  962. assert(flags->type == cg_reg_type_flags);
  963. assert(source->type == cg_reg_type_general);
  964. inst->unary.dest_value = dest;
  965. inst->unary.dest_flags = flags;
  966. inst->unary.operand.source = source;
  967. return inst;
  968. }
  969. cg_inst_t * cg_create_inst_binary(cg_block_t * block,
  970. cg_opcode_t op,
  971. cg_virtual_reg_t * dest,
  972. cg_virtual_reg_t * source,
  973. cg_virtual_reg_t * operand
  974. CG_INST_DEBUG_ARG_DECL)
  975. {
  976. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_binary_t), cg_inst_binary, op CG_INST_DEBUG_PASS);
  977. assert(dest->type == cg_reg_type_general);
  978. assert(source->type == cg_reg_type_general);
  979. assert(operand->type == cg_reg_type_general);
  980. inst->binary.dest_value = dest;
  981. inst->binary.source = source;
  982. inst->binary.operand.source = operand;
  983. return inst;
  984. }
  985. cg_inst_t * cg_create_inst_binary_s(cg_block_t * block,
  986. cg_opcode_t op,
  987. cg_virtual_reg_t * dest,
  988. cg_virtual_reg_t * flags,
  989. cg_virtual_reg_t * source,
  990. cg_virtual_reg_t * operand
  991. CG_INST_DEBUG_ARG_DECL)
  992. {
  993. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_binary_t), cg_inst_binary, op CG_INST_DEBUG_PASS);
  994. assert(dest->type == cg_reg_type_general);
  995. assert(flags->type == cg_reg_type_flags);
  996. assert(source->type == cg_reg_type_general);
  997. assert(operand->type == cg_reg_type_general);
  998. inst->binary.dest_value = dest;
  999. inst->binary.dest_flags = flags;
  1000. inst->binary.source = source;
  1001. inst->binary.operand.source = operand;
  1002. return inst;
  1003. }
  1004. cg_inst_t * cg_create_inst_compare(cg_block_t * block,
  1005. cg_opcode_t op,
  1006. cg_virtual_reg_t * dest,
  1007. cg_virtual_reg_t * source,
  1008. cg_virtual_reg_t * operand
  1009. CG_INST_DEBUG_ARG_DECL)
  1010. {
  1011. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_compare_t), cg_inst_compare, op CG_INST_DEBUG_PASS);
  1012. assert(dest->type == cg_reg_type_flags);
  1013. assert(source->type == cg_reg_type_general);
  1014. assert(operand->type == cg_reg_type_general);
  1015. inst->compare.dest_flags = dest;
  1016. inst->compare.source = source;
  1017. inst->compare.operand.source = operand;
  1018. return inst;
  1019. }
  1020. cg_inst_t * cg_create_inst_load(cg_block_t * block,
  1021. cg_opcode_t op,
  1022. cg_virtual_reg_t * dest,
  1023. cg_virtual_reg_t * mem
  1024. CG_INST_DEBUG_ARG_DECL)
  1025. {
  1026. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_load_t), cg_inst_load, op CG_INST_DEBUG_PASS);
  1027. assert(dest->type == cg_reg_type_general);
  1028. assert(mem->type == cg_reg_type_general);
  1029. inst->load.dest = dest;
  1030. inst->load.mem.base = mem;
  1031. return inst;
  1032. }
  1033. cg_inst_t * cg_create_inst_store(cg_block_t * block,
  1034. cg_opcode_t op,
  1035. cg_virtual_reg_t * source,
  1036. cg_virtual_reg_t * mem
  1037. CG_INST_DEBUG_ARG_DECL)
  1038. {
  1039. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_store_t), cg_inst_store, op CG_INST_DEBUG_PASS);
  1040. assert(source->type == cg_reg_type_general);
  1041. assert(mem->type == cg_reg_type_general);
  1042. inst->store.source = source;
  1043. inst->store.mem.base = mem;
  1044. return inst;
  1045. }
  1046. cg_inst_t * cg_create_inst_load_immed(cg_block_t * block,
  1047. cg_opcode_t op,
  1048. cg_virtual_reg_t * dest,
  1049. U32 value
  1050. CG_INST_DEBUG_ARG_DECL)
  1051. {
  1052. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_load_immed_t), cg_inst_load_immed, op CG_INST_DEBUG_PASS);
  1053. assert(dest->type == cg_reg_type_general);
  1054. inst->immed.dest = dest;
  1055. inst->immed.value = value;
  1056. return inst;
  1057. }
  1058. cg_inst_t * cg_create_inst_branch_label(cg_block_t * block,
  1059. cg_opcode_t op,
  1060. cg_block_ref_t * target
  1061. CG_INST_DEBUG_ARG_DECL)
  1062. {
  1063. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_branch_t), cg_inst_branch_label, op CG_INST_DEBUG_PASS);
  1064. inst->branch.target = target;
  1065. return inst;
  1066. }
  1067. cg_inst_t * cg_create_inst_branch_cond(cg_block_t * block,
  1068. cg_opcode_t op,
  1069. cg_virtual_reg_t * flags,
  1070. cg_block_ref_t * target
  1071. CG_INST_DEBUG_ARG_DECL)
  1072. {
  1073. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_branch_t), cg_inst_branch_cond, op CG_INST_DEBUG_PASS);
  1074. assert(flags->type == cg_reg_type_flags);
  1075. inst->branch.cond = flags;
  1076. inst->branch.target = target;
  1077. return inst;
  1078. }
  1079. cg_inst_t * cg_create_inst_phi(cg_block_t * block,
  1080. cg_opcode_t op,
  1081. cg_virtual_reg_t * dest,
  1082. cg_virtual_reg_list_t * regs
  1083. CG_INST_DEBUG_ARG_DECL)
  1084. {
  1085. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_phi_t), cg_inst_phi, op CG_INST_DEBUG_PASS);
  1086. inst->phi.dest = dest;
  1087. inst->phi.regs = regs;
  1088. return inst;
  1089. }
  1090. cg_inst_t * cg_create_inst_call_proc(cg_block_t * block,
  1091. cg_opcode_t op,
  1092. cg_proc_t * proc,
  1093. cg_virtual_reg_list_t * args
  1094. CG_INST_DEBUG_ARG_DECL)
  1095. {
  1096. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_call_t), cg_inst_call, op CG_INST_DEBUG_PASS);
  1097. inst->call.proc = proc;
  1098. inst->call.args = args;
  1099. return inst;
  1100. }
  1101. cg_inst_t * cg_create_inst_call_func(cg_block_t * block,
  1102. cg_opcode_t op,
  1103. cg_virtual_reg_t * dest,
  1104. cg_proc_t * proc,
  1105. cg_virtual_reg_list_t * args
  1106. CG_INST_DEBUG_ARG_DECL)
  1107. {
  1108. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_call_t), cg_inst_call, op CG_INST_DEBUG_PASS);
  1109. assert(dest->type == cg_reg_type_general);
  1110. inst->call.dest = dest;
  1111. inst->call.proc = proc;
  1112. inst->call.args = args;
  1113. return inst;
  1114. }
  1115. cg_inst_t * cg_create_inst_ret(cg_block_t * block,
  1116. cg_opcode_t op
  1117. CG_INST_DEBUG_ARG_DECL)
  1118. {
  1119. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_ret_t), cg_inst_ret, op CG_INST_DEBUG_PASS);
  1120. /* nothing */
  1121. return inst;
  1122. }
  1123. cg_inst_t * cg_create_inst_ret_value(cg_block_t * block,
  1124. cg_opcode_t op,
  1125. cg_virtual_reg_t * value
  1126. CG_INST_DEBUG_ARG_DECL)
  1127. {
  1128. cg_inst_t * inst = inst_create(block, sizeof(cg_inst_ret_t), cg_inst_ret, op CG_INST_DEBUG_PASS);
  1129. assert(value->type == cg_reg_type_general);
  1130. inst->ret.result = value;
  1131. return inst;
  1132. }
  1133. cg_block_ref_t * cg_block_ref_create(cg_proc_t * proc)
  1134. {
  1135. cg_block_ref_t * result = (cg_block_ref_t *) cg_heap_allocate(proc->module->heap, sizeof(cg_block_ref_t));
  1136. return result;
  1137. }
  1138. static const char * const opcodes[] =
  1139. {
  1140. "nop",
  1141. "add", "and", "asr", "cmp", "div",
  1142. "lsl", "lsr", "mod", "mul", "neg",
  1143. "not", "or", "sub", "xor",
  1144. "min", "max",
  1145. "fadd", "fcmp", "fdiv", "fmul", "fneg",
  1146. "fsub", "finv", "fsqrt", "abs", "log2",
  1147. "trunc", "round", "fcnv",
  1148. "beq", "bge", "ble", "bgt", "blt",
  1149. "bne", "bra",
  1150. "ldb", "ldh", "ldi", "ldw", "stb",
  1151. "sth", "stw",
  1152. "call", "ret", "phi"
  1153. };
  1154. static const char * const shift_opcodes[] =
  1155. {
  1156. "lsl",
  1157. "lsr",
  1158. "asr",
  1159. "ror"
  1160. }
  1161. ;
  1162. static void inst_dump(cg_inst_t * inst, FILE * out)
  1163. {
  1164. cg_virtual_reg_list_t * list;
  1165. #ifndef NDEBUG
  1166. fprintf(out, "%8.8s %5.5d: ", inst->base.file, inst->base.line);
  1167. #endif
  1168. switch (inst->base.kind)
  1169. {
  1170. case cg_inst_unary:
  1171. if (inst->unary.dest_flags)
  1172. {
  1173. fprintf(out, "\t%s\t(r%d, r%d), r%d\n", opcodes[inst->base.opcode],
  1174. inst->unary.dest_value->reg_no, inst->unary.dest_flags->reg_no, inst->unary.operand.source->reg_no);
  1175. }
  1176. else
  1177. {
  1178. fprintf(out, "\t%s\tr%d, r%d\n", opcodes[inst->base.opcode],
  1179. inst->unary.dest_value->reg_no, inst->unary.operand.source->reg_no);
  1180. }
  1181. break;
  1182. case cg_inst_binary:
  1183. if (inst->binary.dest_flags)
  1184. {
  1185. fprintf(out, "\t%s\t(r%d, r%d), r%d, r%d\n", opcodes[inst->base.opcode],
  1186. inst->binary.dest_value->reg_no, inst->binary.dest_flags->reg_no,
  1187. inst->binary.source->reg_no,
  1188. inst->binary.operand.source->reg_no);
  1189. }
  1190. else
  1191. {
  1192. fprintf(out, "\t%s\tr%d, r%d, r%d\n", opcodes[inst->base.opcode],
  1193. inst->binary.dest_value->reg_no, inst->binary.source->reg_no,
  1194. inst->binary.operand.source->reg_no);
  1195. }
  1196. break;
  1197. case cg_inst_compare:
  1198. fprintf(out, "\t%s\tr%d, r%d, r%d\n", opcodes[inst->base.opcode],
  1199. inst->compare.dest_flags->reg_no, inst->compare.source->reg_no,
  1200. inst->compare.operand.source->reg_no);
  1201. break;
  1202. case cg_inst_load:
  1203. fprintf(out, "\t%s\tr%d, r%d\n", opcodes[inst->base.opcode],
  1204. inst->load.dest->reg_no, inst->load.mem.base->reg_no);
  1205. break;
  1206. case cg_inst_store:
  1207. fprintf(out, "\t%s\tr%d, r%d\n", opcodes[inst->base.opcode],
  1208. inst->store.source->reg_no, inst->store.mem.base->reg_no);
  1209. break;
  1210. case cg_inst_load_immed:
  1211. fprintf(out, "\t%s\tr%d, %d\n", opcodes[inst->base.opcode],
  1212. inst->immed.dest->reg_no, inst->immed.value);
  1213. break;
  1214. case cg_inst_branch_label:
  1215. fprintf(out, "\t%s\t%p\n", opcodes[inst->base.opcode],
  1216. inst->branch.target->block);
  1217. break;
  1218. case cg_inst_branch_cond:
  1219. fprintf(out, "\t%s\tr%d, %p\n", opcodes[inst->base.opcode],
  1220. inst->branch.cond->reg_no, inst->branch.target->block);
  1221. break;
  1222. case cg_inst_phi:
  1223. fprintf(out, "\t%s\tr%d", opcodes[inst->base.opcode],
  1224. inst->phi.dest->reg_no);
  1225. for (list = inst->phi.regs; list; list = list->next)
  1226. {
  1227. fprintf(out, ", r%d", list->reg->reg_no);
  1228. }
  1229. fprintf(out, "\n");
  1230. break;
  1231. case cg_inst_call:
  1232. if (inst->call.dest)
  1233. {
  1234. fprintf(out, "\t%s\tr%d, %p", opcodes[inst->base.opcode],
  1235. inst->call.dest->reg_no, inst->call.proc);
  1236. }
  1237. else
  1238. {
  1239. fprintf(out, "\t%s\t%p", opcodes[inst->base.opcode],
  1240. inst->call.proc);
  1241. }
  1242. for (list = inst->call.args; list; list = list->next)
  1243. {
  1244. fprintf(out, ", r%d", list->reg->reg_no);
  1245. }
  1246. fprintf(out, "\n");
  1247. break;
  1248. case cg_inst_ret:
  1249. if (inst->ret.result)
  1250. {
  1251. fprintf(out, "\t%s\tr%d\n", opcodes[inst->base.opcode],
  1252. inst->ret.result->reg_no);
  1253. }
  1254. else
  1255. {
  1256. fprintf(out, "\t%s\n", opcodes[inst->base.opcode]);
  1257. }
  1258. break;
  1259. case cg_inst_arm_unary_immed:
  1260. if (inst->unary.dest_flags)
  1261. {
  1262. fprintf(out, "\t%s\t(r%d, r%d), %d\n", opcodes[inst->base.opcode],
  1263. inst->unary.dest_value->reg_no, inst->unary.dest_flags->reg_no, inst->unary.operand.immed);
  1264. }
  1265. else
  1266. {
  1267. fprintf(out, "\t%s\tr%d, %d\n", opcodes[inst->base.opcode],
  1268. inst->unary.dest_value->reg_no, inst->unary.operand.immed);
  1269. }
  1270. break;
  1271. case cg_inst_arm_unary_shift_reg:
  1272. if (inst->unary.dest_flags)
  1273. {
  1274. fprintf(out, "\t%s\t(r%d, r%d), r%d %s r%d\n", opcodes[inst->base.opcode],
  1275. inst->unary.dest_value->reg_no, inst->unary.dest_flags->reg_no,
  1276. inst->unary.operand.shift_reg.source->reg_no,
  1277. shift_opcodes[inst->unary.operand.shift_reg.op],
  1278. inst->unary.operand.shift_reg.shift->reg_no);
  1279. }
  1280. else
  1281. {
  1282. fprintf(out, "\t%s\tr%d, r%d %s r%d\n", opcodes[inst->base.opcode],
  1283. inst->unary.dest_value->reg_no,
  1284. inst->unary.operand.shift_reg.source->reg_no,
  1285. shift_opcodes[inst->unary.operand.shift_reg.op],
  1286. inst->unary.operand.shift_reg.shift->reg_no);
  1287. }
  1288. break;
  1289. case cg_inst_arm_unary_shift_immed:
  1290. if (inst->unary.dest_flags)
  1291. {
  1292. fprintf(out, "\t%s\t(r%d, r%d), r%d %s %d\n", opcodes[inst->base.opcode],
  1293. inst->unary.dest_value->reg_no, inst->unary.dest_flags->reg_no,
  1294. inst->unary.operand.shift_immed.source->reg_no,
  1295. shift_opcodes[inst->unary.operand.shift_immed.op],
  1296. inst->unary.operand.shift_immed.shift);
  1297. }
  1298. else
  1299. {
  1300. fprintf(out, "\t%s\tr%d, r%d %s %d\n", opcodes[inst->base.opcode],
  1301. inst->unary.dest_value->reg_no,
  1302. inst->unary.operand.shift_immed.source->reg_no,
  1303. shift_opcodes[inst->unary.operand.shift_immed.op],
  1304. inst->unary.operand.shift_immed.shift);
  1305. }
  1306. break;
  1307. case cg_inst_arm_binary_immed:
  1308. if (inst->binary.dest_flags)
  1309. {
  1310. fprintf(out, "\t%s\t(r%d, r%d), r%d, %d\n", opcodes[inst->base.opcode],
  1311. inst->binary.dest_value->reg_no, inst->binary.dest_flags->reg_no,
  1312. inst->binary.source->reg_no,
  1313. inst->binary.operand.immed);
  1314. }
  1315. else
  1316. {
  1317. fprintf(out, "\t%s\tr%d, r%d, %d\n", opcodes[inst->base.opcode],
  1318. inst->binary.dest_value->reg_no,
  1319. inst->binary.source->reg_no,
  1320. inst->binary.operand.immed);
  1321. }
  1322. break;
  1323. case cg_inst_arm_binary_shift_reg:
  1324. if (inst->binary.dest_flags)
  1325. {
  1326. fprintf(out, "\t%s\t(r%d, r%d), r%d, r%d %s r%d\n", opcodes[inst->base.opcode],
  1327. inst->binary.dest_value->reg_no, inst->binary.dest_flags->reg_no,
  1328. inst->binary.source->reg_no,
  1329. inst->binary.operand.shift_reg.source->reg_no,
  1330. shift_opcodes[inst->binary.operand.shift_reg.op],
  1331. inst->binary.operand.shift_reg.shift->reg_no);
  1332. }
  1333. else
  1334. {
  1335. fprintf(out, "\t%s\tr%d, r%d, r%d %s r%d\n", opcodes[inst->base.opcode],
  1336. inst->binary.dest_value->reg_no,
  1337. inst->binary.source->reg_no,
  1338. inst->binary.operand.shift_reg.source->reg_no,
  1339. shift_opcodes[inst->binary.operand.shift_reg.op],
  1340. inst->binary.operand.shift_reg.shift->reg_no);
  1341. }
  1342. break;
  1343. case cg_inst_arm_binary_shift_immed:
  1344. if (inst->binary.dest_flags)
  1345. {
  1346. fprintf(out, "\t%s\t(r%d, r%d), r%d, r%d %s %d\n", opcodes[inst->base.opcode],
  1347. inst->binary.dest_value->reg_no, inst->binary.dest_flags->reg_no,
  1348. inst->binary.source->reg_no,
  1349. inst->binary.operand.shift_immed.source->reg_no,
  1350. shift_opcodes[inst->binary.operand.shift_immed.op],
  1351. inst->binary.operand.shift_immed.shift);
  1352. }
  1353. else
  1354. {
  1355. fprintf(out, "\t%s\tr%d, r%d, r%d %s %d\n", opcodes[inst->base.opcode],
  1356. inst->binary.dest_value->reg_no,
  1357. inst->binary.source->reg_no,
  1358. inst->binary.operand.shift_immed.source->reg_no,
  1359. shift_opcodes[inst->binary.operand.shift_immed.op],
  1360. inst->binary.operand.shift_immed.shift);
  1361. }
  1362. break;
  1363. case cg_inst_arm_compare_immed:
  1364. fprintf(out, "\t%s\tr%d, r%d, %d\n", opcodes[inst->base.opcode],
  1365. inst->compare.dest_flags->reg_no, inst->compare.source->reg_no,
  1366. inst->compare.operand.immed);
  1367. break;
  1368. case cg_inst_arm_compare_shift_reg:
  1369. fprintf(out, "\t%s\tr%d, r%d, r%d %s r%d\n", opcodes[inst->base.opcode],
  1370. inst->compare.dest_flags->reg_no, inst->compare.source->reg_no,
  1371. inst->compare.operand.shift_reg.source->reg_no,
  1372. shift_opcodes[inst->compare.operand.shift_reg.op],
  1373. inst->compare.operand.shift_reg.shift->reg_no);
  1374. break;
  1375. case cg_inst_arm_compare_shift_immed:
  1376. fprintf(out, "\t%s\tr%d, r%d, r%d %s %d\n", opcodes[inst->base.opcode],
  1377. inst->compare.dest_flags->reg_no, inst->compare.source->reg_no,
  1378. inst->compare.operand.shift_immed.source->reg_no,
  1379. shift_opcodes[inst->compare.operand.shift_immed.op],
  1380. inst->compare.operand.shift_immed.shift);
  1381. break;
  1382. case cg_inst_arm_load_immed_offset:
  1383. fprintf(out, "\t%s\tr%d, (r%d, %d)\n", opcodes[inst->base.opcode],
  1384. inst->load.dest->reg_no, inst->load.mem.immed_offset.base->reg_no,
  1385. inst->load.mem.immed_offset.offset);
  1386. break;
  1387. case cg_inst_arm_load_reg_offset:
  1388. fprintf(out, "\t%s\tr%d, (r%d, r%d)\n", opcodes[inst->base.opcode],
  1389. inst->load.dest->reg_no, inst->load.mem.reg_offset.base->reg_no,
  1390. inst->load.mem.reg_offset.offset->reg_no);
  1391. break;
  1392. case cg_inst_arm_store_immed_offset:
  1393. fprintf(out, "\t%s\tr%d, (r%d, %d)\n", opcodes[inst->base.opcode],
  1394. inst->store.source->reg_no, inst->store.mem.immed_offset.base->reg_no,
  1395. inst->store.mem.immed_offset.offset);
  1396. break;
  1397. case cg_inst_arm_store_reg_offset:
  1398. fprintf(out, "\t%s\tr%d, (r%d, r%d)\n", opcodes[inst->base.opcode],
  1399. inst->store.source->reg_no, inst->store.mem.reg_offset.base->reg_no,
  1400. inst->store.mem.reg_offset.offset->reg_no);
  1401. break;
  1402. case cg_inst_none:
  1403. default:
  1404. fprintf(out, "\t<ILLEGAL INSTRUCTION>\n");
  1405. ;
  1406. }
  1407. }
  1408. static void dump_bitset(const char * name, cg_bitset_t * bitset, FILE * out)
  1409. {
  1410. if (bitset)
  1411. {
  1412. const char * separator = " ";
  1413. size_t index;
  1414. fprintf(out, "; %s = {", name);
  1415. for (index = 0; index < bitset->elements; ++index)
  1416. {
  1417. if (CG_BITSET_TEST(bitset, index))
  1418. {
  1419. fprintf(out, "%s%d", separator, index);
  1420. separator = ", ";
  1421. }
  1422. }
  1423. fprintf(out, " }\n");
  1424. }
  1425. }
  1426. void dump_register_info(cg_virtual_reg_t * reg, FILE * out)
  1427. {
  1428. cg_virtual_reg_list_t * list;
  1429. fprintf(out, "\tr%d [U: $%d, D: $%d] => ", reg->reg_no, reg->use_cost, reg->def_cost);
  1430. for (list = reg->interferences; list; list = list->next)
  1431. {
  1432. fprintf(out, "%d ", list->reg->reg_no);
  1433. }
  1434. fprintf(out, "\n");
  1435. }
  1436. void cg_module_dump(cg_module_t * module, FILE * out)
  1437. {
  1438. cg_proc_t * proc;
  1439. cg_block_t * block;
  1440. cg_inst_t * inst;
  1441. cg_virtual_reg_t * reg;
  1442. for (proc = module->procs; proc; proc = proc->next)
  1443. {
  1444. for (block = proc->blocks; block; block = block->next)
  1445. {
  1446. fprintf(out, "%p:\n", block);
  1447. dump_bitset("def", block->def, out);
  1448. dump_bitset("use", block->use, out);
  1449. dump_bitset("in", block->live_in, out);
  1450. dump_bitset("out", block->live_out, out);
  1451. for (inst = block->insts.head; inst; inst = inst->base.next)
  1452. {
  1453. inst_dump(inst, out);
  1454. }
  1455. fprintf(out, "\n");
  1456. }
  1457. fprintf(out, "\n\n");
  1458. fprintf(out, "Interference information\n");
  1459. for (reg = proc->registers; reg; reg = reg->next)
  1460. {
  1461. if (reg->representative == NULL || reg->representative == reg)
  1462. dump_register_info(reg, out);
  1463. }
  1464. }
  1465. }
  1466. static void inst_list_append(cg_inst_list_head_t * insts, cg_inst_t * inst)
  1467. {
  1468. if (insts->head)
  1469. {
  1470. assert(insts->tail);
  1471. insts->tail->base.next = inst;
  1472. inst->base.next = NULL;
  1473. insts->tail = inst;
  1474. }
  1475. else
  1476. {
  1477. assert(!insts->tail);
  1478. inst->base.next = NULL;
  1479. insts->head = insts->tail = inst;
  1480. }
  1481. }
  1482. static void block_reschedule(cg_block_t * block, cg_inst_list_head_t * insts)
  1483. {
  1484. }
  1485. static void block_reorder_instructions(cg_block_t * block)
  1486. {
  1487. // phi, branch, ret have to stay in order
  1488. cg_inst_t * insts = block->insts.head;
  1489. block->insts.head = block->insts.tail = NULL;
  1490. /* copy all phi instructions back in place */
  1491. while (insts && insts->base.opcode == cg_op_phi)
  1492. {
  1493. cg_inst_t * inst = insts;
  1494. insts = inst->base.next;
  1495. inst_list_append(&block->insts, inst);
  1496. }
  1497. while (insts)
  1498. {
  1499. /* collect the next sequence of instructions until we reach a branch or ret */
  1500. cg_inst_list_head_t temp_list;
  1501. cg_inst_t * last_inst;
  1502. memset(&temp_list, 0, sizeof temp_list);
  1503. do
  1504. {
  1505. last_inst = insts;
  1506. insts = insts->base.next;
  1507. inst_list_append(&temp_list, last_inst);
  1508. }
  1509. while (insts && last_inst->base.opcode != cg_op_beq &&
  1510. last_inst->base.opcode != cg_op_bne &&
  1511. last_inst->base.opcode != cg_op_blt &&
  1512. last_inst->base.opcode != cg_op_bgt &&
  1513. last_inst->base.opcode != cg_op_ble &&
  1514. last_inst->base.opcode != cg_op_bge &&
  1515. last_inst->base.opcode != cg_op_bra &&
  1516. last_inst->base.opcode != cg_op_ret);
  1517. block_reschedule(block, &temp_list);
  1518. }
  1519. }
  1520. void cg_module_reorder_instructions(cg_module_t * module)
  1521. {
  1522. cg_proc_t * proc;
  1523. cg_block_t * block;
  1524. for (proc = module->procs; proc; proc = proc->next)
  1525. {
  1526. for (block = proc->blocks; block; block = block->next)
  1527. {
  1528. block_reorder_instructions(block);
  1529. }
  1530. }
  1531. }
  1532. static void count_uses(int * result, cg_block_t * block)
  1533. {
  1534. cg_inst_t * inst;
  1535. size_t num_registers = block->proc->num_registers;
  1536. size_t regno;
  1537. for (regno = 0; regno != num_registers; ++regno)
  1538. {
  1539. result[regno] = 0;
  1540. }
  1541. for (inst = block->insts.head; inst != (cg_inst_t *) 0; inst = inst->base.next)
  1542. {
  1543. cg_virtual_reg_t * buffer[64];
  1544. cg_virtual_reg_t **iter, ** end = cg_inst_use(inst, buffer, buffer + 64);
  1545. for (iter = buffer; iter != end; ++iter)
  1546. {
  1547. regno = (*iter)->reg_no;
  1548. ++result[regno];
  1549. }
  1550. }
  1551. }
  1552. static void block_interferences(cg_block_t * block)
  1553. {
  1554. cg_proc_t * proc = block->proc;
  1555. cg_heap_t * heap = proc->module->heap;
  1556. cg_inst_t * inst;
  1557. size_t outer_index, inner_index;
  1558. // for any registers live in input, create an edge and add them to current list of live registers
  1559. // create list of uses for each instruction
  1560. // iterate over instructions:
  1561. // for each def, add edge to all live registers
  1562. // add def to live registers
  1563. // for each use, remove current use from use list; if # uses = 0 and not in live out, remove variable from live register set
  1564. cg_bitset_t * live = cg_bitset_create(heap, block->live_in->elements);
  1565. int * uses = (int *) malloc(sizeof(int *) * proc->num_registers);
  1566. assert(proc->num_registers == block->live_in->elements);
  1567. count_uses(uses, block);
  1568. cg_bitset_assign(live, block->live_in);
  1569. for (outer_index = 0; outer_index < live->elements - 1; ++outer_index)
  1570. {
  1571. if (!CG_BITSET_TEST(live, outer_index))
  1572. continue;
  1573. for (inner_index = outer_index + 1; inner_index < live->elements; ++inner_index)
  1574. {
  1575. if (CG_BITSET_TEST(live, inner_index))
  1576. {
  1577. add_interference(heap, block->proc->reg_array[outer_index],
  1578. block->proc->reg_array[inner_index]);
  1579. add_interference(heap, block->proc->reg_array[inner_index],
  1580. block->proc->reg_array[outer_index]);
  1581. }
  1582. }
  1583. }
  1584. for (inst = block->insts.head; inst != NULL; inst = inst->base.next)
  1585. {
  1586. cg_virtual_reg_t * buffer[64], * representative;
  1587. cg_virtual_reg_t **iter, ** end = cg_inst_def(inst, buffer, buffer + 64);
  1588. for (iter = buffer; iter != end; ++iter)
  1589. {
  1590. // add an edge between def register and each element in live set
  1591. // add def to live set
  1592. if (!CG_BITSET_TEST(live, (*iter)->reg_no))
  1593. {
  1594. for (inner_index = 0; inner_index < live->elements; ++inner_index)
  1595. {
  1596. if (CG_BITSET_TEST(live, inner_index))
  1597. {
  1598. add_interference(heap, block->proc->reg_array[(*iter)->reg_no],
  1599. block->proc->reg_array[inner_index]);
  1600. add_interference(heap, block->proc->reg_array[inner_index],
  1601. block->proc->reg_array[(*iter)->reg_no]);
  1602. }
  1603. }
  1604. CG_BITSET_SET(live, (*iter)->reg_no);
  1605. }
  1606. representative = *iter;
  1607. if (representative->representative != NULL && representative->representative != representative)
  1608. representative = representative->representative;
  1609. if (CG_BITSET_TEST(block->live_out, representative->reg_no))
  1610. representative->def_cost += block->weight;
  1611. }
  1612. end = cg_inst_use(inst, buffer, buffer + 64);
  1613. for (iter = buffer; iter != end; ++iter)
  1614. {
  1615. assert((*iter)->reg_no >= 0);
  1616. assert((*iter)->reg_no < proc->num_registers);
  1617. --uses[(*iter)->reg_no];
  1618. if (uses[(*iter)->reg_no] == 0 && !CG_BITSET_TEST(block->live_out, (*iter)->reg_no))
  1619. CG_BITSET_CLEAR(live, (*iter)->reg_no);
  1620. representative = *iter;
  1621. if (representative->representative != NULL && representative->representative != representative)
  1622. representative = representative->representative;
  1623. /* TO DO: this estimate can be refined in a variety of ways */
  1624. representative->use_cost += block->weight;
  1625. }
  1626. }
  1627. free(uses);
  1628. }
  1629. void cg_module_interferences(cg_module_t * module)
  1630. {
  1631. cg_proc_t * proc;
  1632. cg_block_t * block;
  1633. for (proc = module->procs; proc; proc = proc->next)
  1634. {
  1635. cg_virtual_reg_t * reg;
  1636. proc->reg_array = (cg_virtual_reg_t **) cg_heap_allocate(module->heap, sizeof(cg_virtual_reg_t *) * proc->num_registers);
  1637. for (reg = proc->registers; reg; reg = reg->next)
  1638. {
  1639. proc->reg_array[reg->reg_no] = reg;
  1640. }
  1641. for (block = proc->blocks; block; block = block->next)
  1642. {
  1643. block_interferences(block);
  1644. }
  1645. }
  1646. }