Lines Matching defs:state
169 static const char *show_op(struct bb_state *state, struct operand *op)
235 static void FORMAT_ATTR(2) output_line(struct bb_state *state, const char *fmt, ...)
244 static void FORMAT_ATTR(2) output_label(struct bb_state *state, const char *fmt, ...)
253 output_line(state, "%s:\n", buffer);
256 static void FORMAT_ATTR(2) output_insn(struct bb_state *state, const char *fmt, ...)
265 output_line(state, "\t%s\n", buffer);
268 #define output_insn(state, fmt, arg...) \
269 output_insn(state, fmt "\t\t# %s" , ## arg , __FUNCTION__)
271 static void FORMAT_ATTR(2) output_comment(struct bb_state *state, const char *fmt, ...)
282 output_line(state, "\t# %s\n", buffer);
313 static void alloc_stack(struct bb_state *state, struct storage *storage)
326 static int can_regenerate(struct bb_state *state, pseudo_t pseudo)
336 in = find_storage_hash(pseudo, state->inputs);
339 in = find_storage_hash(pseudo, state->internal);
346 static void flush_one_pseudo(struct bb_state *state, struct hardreg *hardreg, pseudo_t pseudo)
351 if (can_regenerate(state, pseudo))
354 output_comment(state, "flushing %s from %s", show_pseudo(pseudo), hardreg->name);
355 out = find_storage_hash(pseudo, state->internal);
357 out = find_storage_hash(pseudo, state->outputs);
359 out = find_or_create_hash(pseudo, &state->internal);
369 out = find_or_create_hash(pseudo, &state->internal);
373 alloc_stack(state, storage);
376 output_insn(state, "movl %s,%s", hardreg->name, show_memop(storage));
382 static void flush_reg(struct bb_state *state, struct hardreg *reg)
387 output_comment(state, "reg %s flushed while busy is %d!", reg->name, reg->busy);
397 flush_one_pseudo(state, reg, pseudo);
402 static struct storage_hash *find_pseudo_storage(struct bb_state *state, pseudo_t pseudo, struct hardreg *reg)
406 src = find_storage_hash(pseudo, state->internal);
408 src = find_storage_hash(pseudo, state->inputs);
410 src = find_storage_hash(pseudo, state->outputs);
436 alloc_stack(state, src->storage);
441 static void mark_reg_dead(struct bb_state *state, pseudo_t pseudo, struct hardreg *reg)
450 output_comment(state, "marking pseudo %s in reg %s dead", show_pseudo(pseudo), reg->name);
456 static void add_pseudo_reg(struct bb_state *state, pseudo_t pseudo, struct hardreg *reg)
458 output_comment(state, "added pseudo %s to reg %s", show_pseudo(pseudo), reg->name);
462 static struct hardreg *preferred_reg(struct bb_state *state, pseudo_t target)
466 dst = find_storage_hash(target, state->outputs);
475 static struct hardreg *empty_reg(struct bb_state *state)
487 static struct hardreg *target_reg(struct bb_state *state, pseudo_t pseudo, pseudo_t target)
494 reg = preferred_reg(state, target);
498 reg = empty_reg(state);
509 flush_reg(state, reg);
517 add_pseudo_reg(state, pseudo, reg);
521 static struct hardreg *find_in_reg(struct bb_state *state, pseudo_t pseudo)
533 output_comment(state, "found pseudo %s in reg %s (busy=%d)", show_pseudo(pseudo), reg->name, reg->busy);
541 static void flush_pseudo(struct bb_state *state, pseudo_t pseudo, struct storage *storage)
543 struct hardreg *reg = find_in_reg(state, pseudo);
546 flush_reg(state, reg);
549 static void flush_cc_cache_to_reg(struct bb_state *state, pseudo_t pseudo, struct hardreg *reg)
551 int opcode = state->cc_opcode;
553 state->cc_opcode = 0;
554 state->cc_target = NULL;
555 output_insn(state, "%s %s", opcodes[opcode], reg->name);
558 static void flush_cc_cache(struct bb_state *state)
560 pseudo_t pseudo = state->cc_target;
565 state->cc_target = NULL;
567 if (!state->cc_dead) {
568 dst = target_reg(state, pseudo, pseudo);
569 flush_cc_cache_to_reg(state, pseudo, dst);
574 static void add_cc_cache(struct bb_state *state, int opcode, pseudo_t pseudo)
576 assert(!state->cc_target);
577 state->cc_target = pseudo;
578 state->cc_opcode = opcode;
579 state->cc_dead = 0;
580 output_comment(state, "caching %s", opcodes[opcode]);
584 static struct hardreg *fill_reg(struct bb_state *state, struct hardreg *hardreg, pseudo_t pseudo)
589 if (state->cc_target == pseudo) {
590 flush_cc_cache_to_reg(state, pseudo, hardreg);
596 output_insn(state, "movl $%lld,%s", pseudo->value, hardreg->name);
599 src = find_pseudo_storage(state, pseudo, NULL);
602 output_insn(state, "movl $<%s>,%s", show_pseudo(pseudo), hardreg->name);
608 src = find_or_create_hash(pseudo, &state->internal);
611 alloc_stack(state, src->storage);
615 flush_pseudo(state, pseudo, src->storage);
616 output_insn(state, "leal %s,%s", show_memop(src->storage), hardreg->name);
624 output_insn(state, "movl $<%s>,%s", show_pseudo(def->target), hardreg->name);
627 src = find_pseudo_storage(state, pseudo, hardreg);
631 mark_reg_dead(state, pseudo, hardreg);
632 output_insn(state, "mov.%d %s,%s", 32, show_memop(src->storage), hardreg->name);
635 output_insn(state, "reload %s from %s", hardreg->name, show_pseudo(pseudo));
641 static struct hardreg *getreg(struct bb_state *state, pseudo_t pseudo, pseudo_t target)
645 reg = find_in_reg(state, pseudo);
648 reg = target_reg(state, pseudo, target);
649 return fill_reg(state, reg, pseudo);
652 static void move_reg(struct bb_state *state, struct hardreg *src, struct hardreg *dst)
654 output_insn(state, "movl %s,%s", src->name, dst->name);
657 static struct hardreg *copy_reg(struct bb_state *state, struct hardreg *src, pseudo_t target)
670 reg = preferred_reg(state, target);
672 output_comment(state, "copying %s to preferred target %s", show_pseudo(target), reg->name);
673 move_reg(state, src, reg);
680 output_comment(state, "copying %s to %s", show_pseudo(target), reg->name);
681 output_insn(state, "movl %s,%s", src->name, reg->name);
686 flush_reg(state, src);
690 static void put_operand(struct bb_state *state, struct operand *op)
715 static struct operand *get_register_operand(struct bb_state *state, pseudo_t pseudo, pseudo_t target)
719 op->reg = getreg(state, pseudo, target);
724 static int get_sym_frame_offset(struct bb_state *state, pseudo_t pseudo)
734 static struct operand *get_generic_operand(struct bb_state *state, pseudo_t pseudo)
756 op->offset = get_sym_frame_offset(state, pseudo);
761 reg = find_in_reg(state, pseudo);
768 hash = find_pseudo_storage(state, pseudo, NULL);
796 static const char *generic(struct bb_state *state, pseudo_t pseudo)
799 struct operand *op = get_generic_operand(state, pseudo);
808 int len = sprintf(buf, "$ %s", show_op(state, op));
813 str = show_op(state, op);
814 put_operand(state, op);
815 reg = target_reg(state, pseudo, NULL);
816 output_insn(state, "lea %s,%s", show_op(state, op), reg->name);
820 str = show_op(state, op);
822 put_operand(state, op);
826 static struct operand *get_address_operand(struct bb_state *state, struct instruction *memop)
829 struct operand *op = get_generic_operand(state, memop->src);
836 put_operand(state, op);
837 base = getreg(state, memop->src, NULL);
847 static const char *address(struct bb_state *state, struct instruction *memop)
849 struct operand *op = get_address_operand(state, memop);
850 const char *str = show_op(state, op);
851 put_operand(state, op);
855 static const char *reg_or_imm(struct bb_state *state, pseudo_t pseudo)
861 return getreg(state, pseudo, NULL)->name;
881 static struct hardreg *target_copy_reg(struct bb_state *state, struct hardreg *src, pseudo_t target)
884 return copy_reg(state, src, target);
887 static void do_binop(struct bb_state *state, struct instruction *insn, pseudo_t val1, pseudo_t val2)
890 struct operand *src = get_register_operand(state, val1, insn->target);
891 struct operand *src2 = get_generic_operand(state, val2);
894 dst = target_copy_reg(state, src->reg, insn->target);
895 output_insn(state, "%s.%d %s,%s", op, insn->size, show_op(state, src2), dst->name);
896 put_operand(state, src);
897 put_operand(state, src2);
898 add_pseudo_reg(state, insn->target, dst);
901 static void generate_binop(struct bb_state *state, struct instruction *insn)
903 flush_cc_cache(state);
904 do_binop(state, insn, insn->src1, insn->src2);
907 static int is_dead_reg(struct bb_state *state, pseudo_t pseudo, struct hardreg *reg)
922 static void generate_commutative_binop(struct bb_state *state, struct instruction *insn)
927 flush_cc_cache(state);
930 reg2 = find_in_reg(state, src2);
933 reg1 = find_in_reg(state, src1);
936 if (!is_dead_reg(state, src2, reg2))
938 if (!is_dead_reg(state, src1, reg1))
942 if (reg2 != preferred_reg(state, insn->target))
949 do_binop(state, insn, src1, src2);
957 static void mark_pseudo_dead(struct bb_state *state, pseudo_t pseudo)
962 if (state->cc_target == pseudo)
963 state->cc_dead = 1;
964 src = find_pseudo_storage(state, pseudo, NULL);
968 mark_reg_dead(state, pseudo, hardregs + i);
971 static void kill_dead_pseudos(struct bb_state *state)
980 static void generate_store(struct instruction *insn, struct bb_state *state)
982 output_insn(state, "mov.%d %s,%s", insn->size, reg_or_imm(state, insn->target), address(state, insn));
985 static void generate_load(struct instruction *insn, struct bb_state *state)
987 const char *input = address(state, insn);
990 kill_dead_pseudos(state);
991 dst = target_reg(state, insn->target, NULL);
992 output_insn(state, "mov.%d %s,%s", insn->size, input, dst->name);
995 static void kill_pseudo(struct bb_state *state, pseudo_t pseudo)
1000 output_comment(state, "killing pseudo %s", show_pseudo(pseudo));
1010 output_comment(state, "removing pseudo %s from reg %s",
1018 static void generate_copy(struct bb_state *state, struct instruction *insn)
1020 struct hardreg *src = getreg(state, insn->src, insn->target);
1021 kill_pseudo(state, insn->target);
1022 add_pseudo_reg(state, insn->target, src);
1025 static void generate_cast(struct bb_state *state, struct instruction *insn)
1027 struct hardreg *src = getreg(state, insn->src, insn->target);
1037 add_pseudo_reg(state, insn->target, src);
1041 dst = target_copy_reg(state, src, insn->target);
1044 output_insn(state, "sext.%d.%d %s", old, new, dst->name);
1049 output_insn(state, "andl.%d $%#llx,%s", insn->size, mask, dst->name);
1051 add_pseudo_reg(state, insn->target, dst);
1054 static void generate_output_storage(struct bb_state *state);
1070 static void generate_branch(struct bb_state *state, struct instruction *br)
1076 if (state->cc_target == br->cond) {
1077 cond = conditional[state->cc_opcode];
1079 struct hardreg *reg = getreg(state, br->cond, NULL);
1080 output_insn(state, "testl %s,%s", reg->name, reg->name);
1084 generate_output_storage(state);
1087 output_insn(state, "j%s .L%p", cond, target);
1090 output_insn(state, "jmp .L%p", target);
1094 static void generate_switch(struct bb_state *state, struct instruction *insn)
1098 generate_output_storage(state);
1099 output_insn(state, "switch on %s", reg->name);
1100 output_insn(state, "unimplemented: %s", show_instruction(insn));
1103 static void generate_ret(struct bb_state *state, struct instruction *ret)
1107 struct hardreg *reg = getreg(state, ret->src, NULL);
1109 output_insn(state, "movl %s,%s", reg->name, wants->name);
1111 output_insn(state, "ret");
1117 static void generate_call(struct bb_state *state, struct instruction *insn)
1123 output_insn(state, "pushl %s", generic(state, arg));
1126 flush_reg(state, hardregs+0);
1127 flush_reg(state, hardregs+1);
1128 flush_reg(state, hardregs+2);
1129 output_insn(state, "call %s", show_pseudo(insn->func));
1131 output_insn(state, "addl $%d,%%esp", offset);
1133 add_pseudo_reg(state, insn->target, hardregs+0);
1136 static void generate_select(struct bb_state *state, struct instruction *insn)
1141 src1 = getreg(state, insn->src2, NULL);
1142 dst = copy_reg(state, src1, insn->target);
1143 add_pseudo_reg(state, insn->target, dst);
1144 src2 = getreg(state, insn->src3, insn->target);
1146 if (state->cc_target == insn->src1) {
1147 cond = conditional[state->cc_opcode];
1149 struct hardreg *reg = getreg(state, insn->src1, NULL);
1150 output_insn(state, "testl %s,%s", reg->name, reg->name);
1154 output_insn(state, "sel%s %s,%s", cond, src2->name, dst->name);
1252 static struct asm_arg *generate_asm_inputs(struct bb_state *state, struct asm_constraint_list *list, struct asm_arg *arg)
1266 string = getreg(state, pseudo, NULL)->name;
1271 orig = find_in_reg(state, pseudo);
1273 move_reg(state, orig, reg);
1275 fill_reg(state, reg, pseudo);
1279 string = generic(state, pseudo);
1283 output_insn(state, "# asm input \"%s\": %s : %s", constraint, show_pseudo(pseudo), string);
1294 static struct asm_arg *generate_asm_outputs(struct bb_state *state, struct asm_constraint_list *list, struct asm_arg *arg)
1311 reg = target_reg(state, pseudo, NULL);
1318 output_insn(state, "# asm output \"%s\": %s : %s", constraint, show_pseudo(pseudo), string);
1327 static void generate_asm(struct bb_state *state, struct instruction *insn)
1334 arg = generate_asm_outputs(state, insn->asm_rules->outputs, asm_arguments);
1335 arg = generate_asm_inputs(state, insn->asm_rules->inputs, arg);
1338 output_insn(state, "%s", str);
1341 static void generate_compare(struct bb_state *state, struct instruction *insn)
1347 flush_cc_cache(state);
1354 src = getreg(state, insn->src1, insn->target);
1355 src2 = generic(state, insn->src2);
1357 output_insn(state, "cmp.%d %s,%s", insn->size, src2, src->name);
1359 add_cc_cache(state, opcode, insn->target);
1362 static void generate_one_insn(struct instruction *insn, struct bb_state *state)
1365 output_comment(state, "%s", show_instruction(insn));
1388 generate_store(insn, state);
1392 generate_load(insn, state);
1396 mark_pseudo_dead(state, insn->target);
1400 generate_copy(state, insn);
1405 generate_commutative_binop(state, insn);
1411 generate_binop(state, insn);
1415 generate_compare(state, insn);
1426 generate_cast(state, insn);
1430 generate_select(state, insn);
1435 generate_branch(state, insn);
1439 generate_switch(state, insn);
1443 generate_call(state, insn);
1447 generate_ret(state, insn);
1451 generate_asm(state, insn);
1457 output_insn(state, "unimplemented: %s", show_instruction(insn));
1460 kill_dead_pseudos(state);
1466 static void write_reg_to_storage(struct bb_state *state, struct hardreg *reg, pseudo_t pseudo, struct storage *storage)
1476 output_insn(state, "movl %s,%s", reg->name, out->name);
1491 output_insn(state, "movl %s,%s", reg->name, out->name);
1499 alloc_stack(state, storage);
1502 output_insn(state, "movl %s,%s", reg->name, show_memop(storage));
1507 static void write_val_to_storage(struct bb_state *state, pseudo_t src, struct storage *storage)
1513 alloc_stack(state, storage);
1515 output_insn(state, "movl %s,%s", show_pseudo(src), show_memop(storage));
1519 output_insn(state, "movl %s,%s", show_pseudo(src), out->name);
1523 static void fill_output(struct bb_state *state, pseudo_t pseudo, struct storage *out)
1532 write_val_to_storage(state, pseudo, out);
1537 write_val_to_storage(state, pseudo, out);
1551 write_reg_to_storage(state, reg, pseudo, out);
1558 in = find_storage_hash(pseudo, state->internal);
1560 in = find_storage_hash(pseudo, state->inputs);
1570 output_insn(state, "movl %s,%s", show_memop(in->storage), hardregs[out->regno].name);
1577 output_insn(state, "movl %s,%s", show_memop(in->storage), show_memop(out));
1583 static int final_pseudo_flush(struct bb_state *state, pseudo_t pseudo, struct hardreg *reg)
1593 hash = find_storage_hash(pseudo, state->outputs);
1609 dst = empty_reg(state);
1618 dst = empty_reg(state);
1629 output_insn(state, "movl %s,%s", reg->name, show_memop(out));
1635 output_insn(state, "movl %s,%s", reg->name, dst->name);
1636 add_pseudo_reg(state, pseudo, dst);
1644 static void generate_output_storage(struct bb_state *state)
1649 FOR_EACH_PTR(state->outputs, entry) {
1666 if (final_pseudo_flush(state, p, reg)) {
1674 flush_reg(state, reg);
1678 FOR_EACH_PTR(state->outputs, entry) {
1679 fill_output(state, entry->pseudo, entry->storage);
1683 static void generate(struct basic_block *bb, struct bb_state *state)
1696 FOR_EACH_PTR(state->inputs, entry) {
1699 output_comment(state, "incoming %s in %s", show_pseudo(entry->pseudo), name);
1702 add_pseudo_reg(state, entry->pseudo, hardregs + regno);
1707 output_label(state, ".L%p", bb);
1711 generate_one_insn(insn, state);
1715 output_comment(state, "--- in ---");
1716 FOR_EACH_PTR(state->inputs, entry) {
1717 output_comment(state, "%s <- %s", show_pseudo(entry->pseudo), show_storage(entry->storage));
1719 output_comment(state, "--- spill ---");
1720 FOR_EACH_PTR(state->internal, entry) {
1721 output_comment(state, "%s <-> %s", show_pseudo(entry->pseudo), show_storage(entry->storage));
1723 output_comment(state, "--- out ---");
1724 FOR_EACH_PTR(state->outputs, entry) {
1725 output_comment(state, "%s -> %s", show_pseudo(entry->pseudo), show_storage(entry->storage));
1748 static void mark_used_registers(struct basic_block *bb, struct bb_state *state)
1768 struct bb_state state;
1775 state.pos = bb->pos;
1776 state.inputs = gather_storage(bb, STOR_IN);
1777 state.outputs = gather_storage(bb, STOR_OUT);
1778 state.internal = NULL;
1779 state.cc_opcode = 0;
1780 state.cc_target = NULL;
1783 mark_used_registers(bb, &state);
1785 generate(bb, &state);
1787 free_ptr_list(&state.inputs);
1788 free_ptr_list(&state.outputs);