⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genop.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 4 页
字号:
            continue;        var_sym *the_var = first_destination.symbol();        assert(the_var != NULL);        sym_node_list_e *the_list_e = read_once->lookup(the_var);        if (the_list_e == NULL)            continue;        if (!instr_uses_var(second_instr, the_var))            continue;        first_instr_node->remove_instr(first_instr);        node_list->remove(first_instr_node->list_e());        delete first_instr_node->list_e();        delete first_instr_node;        first_instr->set_dst(operand());        operand new_operand(first_instr);        if (first_instr->opcode() == io_cpy)          {            in_rrr *first_rrr = (in_rrr *)first_instr;            new_operand = first_rrr->src_op();            new_operand.remove();            delete first_rrr;          }        replace_operand(second_instr, operand(the_var), new_operand);        read_once->remove(the_list_e);        delete the_list_e;        the_var->parent()->remove_sym(the_var);        delete the_var;      }  }static boolean instr_uses_var(instruction *the_instr, var_sym *the_var)  {    assert(the_instr != NULL);    unsigned num_srcs = the_instr->num_srcs();    for (unsigned src_num = 0; src_num < num_srcs; ++src_num)      {        operand this_source = the_instr->src_op(src_num);        if (this_source == operand(the_var))            return TRUE;        if (this_source.is_expr())          {            if (instr_uses_var(this_source.instr(), the_var))                return TRUE;          }      }    return FALSE;  }static void replace_operand(instruction *the_instr, operand old_operand,                            operand new_operand)  {    assert(the_instr != NULL);    unsigned num_srcs = the_instr->num_srcs();    for (unsigned src_num = 0; src_num < num_srcs; ++src_num)      {        operand this_source = the_instr->src_op(src_num);        if (this_source == old_operand)          {            the_instr->set_src_op(src_num, new_operand);            return;          }        if (this_source.is_expr())            replace_operand(this_source.instr(), old_operand, new_operand);      }  }static void prune_out_reads(sym_node_list *sym_list, instruction *the_instr)  {    assert(sym_list != NULL);    assert(the_instr != NULL);    if (sym_list->is_empty())        return;    int num_srcs = the_instr->num_srcs();    for (int src_num = 0; src_num < num_srcs; ++src_num)      {        operand this_op = the_instr->src_op(src_num);        if (this_op.is_symbol())          {            sym_node *this_symbol = this_op.symbol();            assert(this_symbol != NULL);            sym_node_list_e *this_element;            sym_node_list_e *next_element = sym_list->head();            while (next_element != NULL)              {                this_element = next_element;                next_element = this_element->next();                sym_node *test_sym = this_element->contents;                if (test_sym == this_symbol)                  {                    sym_list->remove(this_element);                    delete this_element;                  }              }            if (sym_list->is_empty())                return;          }        else if (this_op.is_expr())          {            instruction *this_instr = this_op.instr();            assert(this_instr != NULL);            prune_out_reads(sym_list, this_instr);            if (this_instr->opcode() == io_ldc)              {                in_ldc *this_ldc = (in_ldc *)this_instr;                immed value = this_ldc->value();                if (value.is_symbol())                  {                    sym_node_list_e *this_element =                            sym_list->lookup(value.symbol());                    if (this_element != NULL)                      {                        sym_list->remove(this_element);                        delete this_element;                      }                  }              }          }      }  }static void remove_writes(sym_node_list *sym_list, tree_node_list *node_list)  {    assert(sym_list != NULL);    if (node_list == NULL)        return;    if (sym_list->is_empty())        return;    tree_node_list_iter the_iter(node_list);    while (!the_iter.is_empty())      {        tree_node *this_node = the_iter.step();        switch (this_node->kind())          {            case TREE_INSTR:              {                tree_instr *this_tree_instr = (tree_instr *)this_node;                instruction *this_instr = this_tree_instr->instr();                assert(this_instr != NULL);                operand destination = this_instr->dst_op();                if (!destination.is_symbol())                    break;                sym_node *this_symbol = destination.symbol();                assert(this_symbol != NULL);                if (!symbol_in_list(sym_list, this_symbol))                    break;                eliminate_write(this_tree_instr);                break;              }            case TREE_IF:              {                tree_if *the_if = (tree_if *)this_node;                remove_writes(sym_list, the_if->header());                remove_writes(sym_list, the_if->then_part());                remove_writes(sym_list, the_if->else_part());                break;              }            default:                /*                 * This should never happen since this function should only be                 * called on lists of instructions and tree_if's.                 */                assert(FALSE);          }      }  }static boolean symbol_in_list(sym_node_list *sym_list, sym_node *the_symbol)  {    return (sym_list->lookup(the_symbol) != NULL);  }static void eliminate_write(tree_instr *writer)  {    tree_node_list_e *the_element = writer->list_e();    assert(the_element != NULL);    tree_node_list *the_list = writer->parent();    assert(the_list != NULL);    instruction *the_instr = writer->instr();    assert(the_instr != NULL);    writer->remove_instr(the_instr);    the_instr->set_dst(operand());    side_effect_list(the_list, the_element, operand(the_instr));    the_list->remove(the_element);    delete writer;    delete the_element;  }static void remove_symbols(sym_node_list *sym_list)  {    assert(sym_list != NULL);    sym_node_list_e *this_element;    sym_node_list_e *next_element = sym_list->head();    while (next_element != NULL)      {        this_element = next_element;        next_element = this_element->next();        sym_node *the_symbol = this_element->contents;        assert(the_symbol != NULL);        the_symbol->parent()->remove_sym(the_symbol);        delete the_symbol;        sym_list->remove(this_element);        delete this_element;      }    assert(sym_list->is_empty());  }static void clean_field_refs_on_tree_node(tree_node *the_node, void *)  {    assert(the_node != NULL);    if (!the_node->is_instr())        return;    tree_instr *the_tree_instr = (tree_instr *)the_node;    instruction *old_instr = the_tree_instr->instr();    assert(old_instr != NULL);    the_tree_instr->remove_instr(old_instr);    instruction *new_instr = clean_field_refs_on_instr(old_instr);    the_tree_instr->set_instr(new_instr);  }static operand clean_field_refs_on_operand(operand to_clean)  {    if (!to_clean.is_expr())        return to_clean;    return operand(clean_field_refs_on_instr(to_clean.instr()));  }static instruction *clean_field_refs_on_instr(instruction *to_clean)  {    operand destination = to_clean->dst_op();    unsigned num_srcs = to_clean->num_srcs();    for (unsigned src_num = 0; src_num < num_srcs; ++src_num)      {        operand old_operand = to_clean->src_op(src_num);        old_operand.remove();        to_clean->set_src_op(src_num,                             clean_field_refs_on_operand(old_operand));      }    if (instr_is_bit_field_ref(to_clean))      {        operand new_operand = expand_bit_field_ref(to_clean);        instruction *new_instr;        if (new_operand.is_expr())          {            new_instr = new_operand.instr();          }        else          {            new_instr = new in_rrr(io_cpy, new_operand.type(), operand(),                                   new_operand);          }        if (destination.is_symbol())          {            new_instr->set_dst(destination);          }        return new_instr;      }    else      {        return to_clean;      }  }static operand expand_bit_field_ref(instruction *to_undo)  {    unsigned short bit_field_from;    unsigned short bit_field_to;    type_node *result_type;    operand address =            undo_bit_field_on_instr(to_undo, &bit_field_from, &bit_field_to,                                    &result_type);    int right_amount = result_type->size() - (bit_field_to - bit_field_from);    int left_amount = right_amount - field_right;    in_rrr *the_load =            new in_rrr(io_lod, unsignedtype, operand(), address);    in_rrr *the_lsl =            new in_rrr(io_lsl, unsignedtype, operand(), operand(the_load),                       operand(new in_ldc(unsignedtype, operand(),                                          immed(left_amount))));    in_rrr *pre_asr;    if_ops right_shift_op;    if (result_type == unsignedtype)      {        pre_asr = the_lsl;        right_shift_op = io_lsr;      }    else      {        pre_asr = new in_rrr(io_cvt, result_type, operand(), operand(the_lsl));        right_shift_op = io_asr;      }    in_rrr *the_asr =            new in_rrr(right_shift_op, result_type, operand(),                       operand(pre_asr),                       operand(new in_ldc(unsignedtype, operand(),                                          immed(right_amount))));    return operand(the_asr);  }static operand undo_bit_field_on_instr(instruction *to_undo,                                       unsigned short *from,                                       unsigned short *to,                                       type_node **result_type)  {    assert(to_undo != NULL);    assert(to_undo->opcode() == io_cal);    in_cal *the_call = (in_cal *)to_undo;    operand result = the_call->argument(0);    result.remove();    operand from_operand = the_call->argument(1);    assert(from_operand.is_expr());    instruction *from_instr = from_operand.instr();    assert(from_instr != NULL);    assert(from_instr->opcode() == io_ldc);    in_ldc *from_ldc = (in_ldc *)from_instr;    immed from_value = from_ldc->value();    assert(from_value.is_integer());    *from = from_value.integer();    operand to_operand = the_call->argument(2);    assert(to_operand.is_expr());    instruction *to_instr = to_operand.instr();    assert(to_instr != NULL);    assert(to_instr->opcode() == io_ldc);    in_ldc *to_ldc = (in_ldc *)to_instr;    immed to_value = to_ldc->value();    assert(to_value.is_integer());    *to = to_value.integer();    *result_type = the_call->result_type();    delete to_undo;    return result;  }static boolean instr_is_bit_field_ref(instruction *to_test)  {    assert(to_test != NULL);    if (to_test->opcode() != io_cal)        return FALSE;    in_cal *the_call = (in_cal *)to_test;    operand address = the_call->addr_op();    if (!address.is_expr())        return FALSE;    instruction *addr_instr = address.instr();    assert(addr_instr != NULL);    if (addr_instr->opcode() != io_ldc)        return FALSE;    in_ldc *the_ldc = (in_ldc *)addr_instr;    immed value = the_ldc->value();    if (!value.is_symbol())        return FALSE;    return (value.symbol() == bit_ref_symbol);  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -