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

📄 genop.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* file "genop.cc" *//*  Copyright (c) 1994 Stanford University    All rights reserved.    This software is provided under the terms described in    the "suif_copyright.h" include file. */#include <suif_copyright.h>/* *  This file contains the implementation of the generalized operand class *  genop. */#include <limits.h>#include "c.h"typedef struct  {    sym_node_list *read_once;    sym_node_list *read_multiple;  } read_once_data;char *k_sequence_point;char *k_bit_field_info;char *k_type_name;char *k_type_source_coordinates;char *k_field_table;char *k_type_alignment;char *k_C_comment;char *k_source_coordinates;char *k_is_declared_reg;char *k_source_references;char *k_builtin_args;char *k_typedef_name;boolean option_keep_comments = FALSE;boolean option_mark_execution_points = FALSE;boolean option_null_check = FALSE;boolean option_keep_typedef_info = FALSE;boolean option_force_enum_is_int = FALSE;static proc_sym *bit_ref_symbol;static void side_effect_list(tree_node_list *the_list,                             tree_node_list_e *position, operand the_operand);static void written_and_not_read(sym_node_list *sym_list,                                 tree_node_list *node_list);static void find_temps_read_once(sym_node_list *sym_list,                                 tree_node_list *node_list);static void prune_once_read_on_node_list(sym_node_list *read_once,                                         sym_node_list *read_multiple,                                         tree_node_list *node_list);static void prune_once_read_on_node(tree_node *the_node, void *data);static void prune_once_read_on_instr(instruction *the_instr, void *data);static void remove_sym_from_list(sym_node_list *the_list, sym_node *symbol);static void attempt_combination(sym_node_list *read_once,                                tree_node_list *node_list);static boolean instr_uses_var(instruction *the_instr, var_sym *the_var);static void replace_operand(instruction *the_instr, operand old_operand,                            operand new_operand);static void prune_out_reads(sym_node_list *sym_list, instruction *the_instr);static void remove_writes(sym_node_list *sym_list, tree_node_list *node_list);static boolean symbol_in_list(sym_node_list *sym_list, sym_node *the_symbol);static void eliminate_write(tree_instr *writer);static void remove_symbols(sym_node_list *sym_list);static void clean_field_refs_on_tree_node(tree_node *the_node, void *);static operand clean_field_refs_on_operand(operand to_clean);static instruction *clean_field_refs_on_instr(instruction *to_clean);static operand expand_bit_field_ref(instruction *to_undo);static operand undo_bit_field_on_instr(instruction *to_undo,                                       unsigned short *from,                                       unsigned short *to,                                       type_node **result_type);static boolean instr_is_bit_field_ref(instruction *to_test);boolean genop::is_addressable(void)  {    if (suif_operand().is_expr())      {        instruction *the_instr = suif_operand().instr();        assert(the_instr != NULL);        return (the_instr->opcode() == io_lod);      }    else if (suif_operand().is_symbol())      {        sym_node *symbol = suif_operand().symbol();        assert(symbol != NULL);        return symbol->is_userdef();      }    else      {        return FALSE;      }  }type_node *genop::type(void)  {    return suif_operand().type();  }tree_node_list *genop::side_effects_only(void)  {    tree_node_list *the_list = precomputation();    side_effect_list(the_list, NULL, suif_operand());    return the_list;  }void genop::make_temporary(void)  {    type_node *this_type = type();    if (suif_operand().is_symbol())      {        sym_node *symbol = suif_operand().symbol();        assert(symbol != NULL);        if (!symbol->is_userdef())            return;      }    else if (suif_operand().is_expr())      {        instruction *the_instr = suif_operand().instr();        assert(the_instr != NULL);        if (the_instr->opcode() == io_ldc)            return;      }    else      {        return;      }    if (needconst)      {        immed const_value;        eval_status status = evaluate_as_const(&const_value);        boolean need_default_value = FALSE;        switch (status)          {            case EVAL_OVERFLOW:                warning("overflow in constant expression\n");                break;            case EVAL_OK:                break;            case EVAL_NOT_CONST:                error("expression must be constant\n");                need_default_value = TRUE;                break;            case EVAL_DIV_BY_ZERO:                error("division by zero in constant expression\n");                need_default_value = TRUE;                break;            case EVAL_UNKNOWN_AT_LINK:                error("constant expression cannot be computed at link time\n");                need_default_value = TRUE;                break;            default:                assert(FALSE);          }        if (need_default_value)          {            if (type()->unqual()->op() == TYPE_FLOAT)                const_value = immed(0.0);            else                const_value = immed(0);          }        if (suif_operand().is_expr())            delete suif_operand().instr();        in_ldc *new_ldc = new in_ldc(type(), operand(), const_value);        the_suif_operand = operand(new_ldc);        return;      }    if (is_boolean_type())        this_type = booleantype;    var_sym *temporary = get_current_symtab()->new_unique_var(this_type);    temporary->reset_userdef();    precomputation()->append(create_assignment(temporary, suif_operand()));    the_suif_operand = operand(temporary);  }boolean genop::is_int_const(void)  {    if (!suif_operand().is_expr())        return FALSE;    instruction *the_instr = suif_operand().instr();    assert(the_instr != NULL);    if (the_instr->opcode() != io_ldc)        return FALSE;    in_ldc *the_ldc = (in_ldc *)the_instr;    return the_ldc->value().is_int_const();  }boolean genop::is_boolean_type(void)  {    if (suif_operand().is_expr())      {        instruction *the_instr = suif_operand().instr();        switch(the_instr->opcode())          {            case io_seq:            case io_sne:            case io_sl:            case io_sle:                return TRUE;            default:                return FALSE;          }      }    else if (suif_operand().is_symbol())      {        sym_node *symbol = suif_operand().symbol();        assert(symbol != NULL);        if (symbol->is_userdef())            return FALSE;        assert(symbol->is_var());        var_sym *the_var = (var_sym *)symbol;        return (the_var->type() == booleantype);      }    else      {        return FALSE;      }  }/* Checks for a ``null pointer constant'' as defined by ANSI/ISO 9899, * Section 6.2.2.3, paragraph 3. */boolean genop::is_null_pointer_constant(void)  {    if (!precomputation()->is_empty())        return FALSE;    if (!suif_operand().is_expr())        return FALSE;    instruction *the_instr = suif_operand().instr();    assert(the_instr != NULL);    while (the_instr->opcode() == io_cvt)      {        in_rrr *the_cvt = (in_rrr *)the_instr;        type_node *cvt_result = the_cvt->result_type();        if (!cvt_result->is_ptr())            break;        ptr_type *result_ptr = (ptr_type *)cvt_result;        type_node *result_ref = result_ptr->ref_type();        if (result_ref->op() != TYPE_VOID)            break;        operand new_op = the_cvt->src_op();        if (!new_op.is_expr())            break;        the_instr = new_op.instr();      }    if (the_instr->opcode() == io_ldc)      {        in_ldc *the_ldc = (in_ldc *)the_instr;        if (the_ldc->value() == immed(0))            return TRUE;      }#ifndef DEAL_WITH_GCC_BRAIN_DAMAGE    genop test_genop(operand(the_instr), precomputation());#else////  gcc version 2.7.2 gets a parse error on the code above.  It looks//  like the same parsing bug in gcc as noted other places where the//  DEAL_WITH_GCC_BRAIN_DAMAGE flag is used.  A work-around folows.//    operand instr_op(the_instr);    genop test_genop(instr_op, precomputation());#endif    if (!test_genop.is_integral_constant_expression())        return FALSE;    immed immed_value;    eval_status result = evaluate_as_const(&immed_value);    return ((result == EVAL_OK) && (immed_value == immed(0)));  }/* Checks for an ``integral constant expression'' as defined by * ANSI/ISO 9899, Section 6.4, sub-section ``Semantics'', paragraph * 2. */boolean genop::is_integral_constant_expression(void)  {    if (!precomputation()->is_empty())        return FALSE;    if (!suif_operand().is_expr())        return FALSE;    instruction *the_instr = suif_operand().instr();    assert(the_instr != NULL);    while (the_instr->opcode() == io_cvt)      {        in_rrr *the_cvt = (in_rrr *)the_instr;        if (the_cvt->result_type()->op() != TYPE_INT)            return FALSE;        operand new_op = the_cvt->src_op();        if (!new_op.is_expr())            return FALSE;        the_instr = new_op.instr();        if (new_op.type()->op() == TYPE_FLOAT)          {            if (the_instr->opcode() != io_ldc)                return FALSE;            in_ldc *the_ldc = (in_ldc *)the_instr;            return the_ldc->value().is_float_const();          }        if (new_op.type()->op() != TYPE_INT)            return FALSE;      }    if (the_instr->opcode() != io_ldc)        return FALSE;    in_ldc *the_ldc = (in_ldc *)the_instr;    return the_ldc->value().is_int_const();  }void genop::make_bit_field_ref(unsigned short from, unsigned short to,                               type_node *result_type)  {    instruction *function =            new in_ldc(voidtype->ptr_to(), operand(), immed(bit_ref_symbol));    in_cal *the_call =            new in_cal(result_type, operand(), operand(function), 3);    the_call->set_argument(0, suif_operand());    the_call->set_argument(1, operand(new in_ldc(inttype, operand(),                                                 immed((int)from))));    the_call->set_argument(2, operand(new in_ldc(inttype, operand(),                                                 immed((int)to))));    the_suif_operand = operand(the_call);  }boolean genop::is_bit_field_ref(void)  {    if (!suif_operand().is_expr())        return FALSE;    instruction *the_instr = suif_operand().instr();    assert(the_instr != NULL);    return instr_is_bit_field_ref(the_instr);  }void genop::undo_bit_field_ref(unsigned short *from, unsigned short *to,                               type_node **result_type)  {    assert(suif_operand().is_expr());    instruction *the_instr = suif_operand().instr();    assert(the_instr != NULL);    the_suif_operand =            undo_bit_field_on_instr(the_instr, from, to, result_type);  }void genop::double_bit_field_ref(genop *op1, genop *op2)  {    assert(is_bit_field_ref());    assert(suif_operand().is_expr());    instruction *the_instr = suif_operand().instr();    assert(the_instr != NULL);    assert(the_instr->opcode() == io_cal);    in_cal *old_call = (in_cal *)the_instr;    assert(old_call->num_args() == 3);    operand base_pointer = old_call->argument(0);    base_pointer.remove();    genop base_genop(base_pointer, precomputation());    base_genop.make_temporary();    in_cal *new_call =            new in_cal(old_call->result_type(), operand(),                       old_call->addr_op().clone(), 3);    new_call->set_argument(0, base_genop.suif_operand().clone());    new_call->set_argument(1, old_call->argument(1).clone());    new_call->set_argument(2, old_call->argument(2).clone());    old_call->set_argument(0, base_genop.suif_operand());    *op1 = genop(operand(old_call), base_genop.precomputation());    *op2 = genop(operand(new_call), new tree_node_list);  }

⌨️ 快捷键说明

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