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

📄 gen.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 3 页
字号:
    the_def->annotes()->append(a);  }// initialize current global symbol with ``size'' bits of empty spacevoid space(var_def *the_def, int size)  {    if (the_def == NULL)        return;    annote *a = new annote(k_fill);    a->immeds()->append(immed(size));    a->immeds()->append(immed(0));    the_def->annotes()->append(a);  }/******************************************************************** * MISCELLANOUS OTHER LCC BACK-END FUNCTIONS                        * ********************************************************************/// stabline - file and line number markervoid stabline(Coordinate *coord)  {    if (curr_list != NULL)      {        instruction *mrk = new in_rrr(io_mrk);        mrk->annotes()->append(make_line_annote(coord));        append_instr(mrk);      }  }/******************************************************************** * ACCESSORY FUNCTIONS FOR CODE GENERATION                          * ********************************************************************/void append_instr(instruction *instr)  {    curr_list->append(new tree_instr(instr));  }/* New stuff */extern void current_list_append_node(tree_node *the_node)  {    assert(curr_list != NULL);    curr_list->append(the_node);  }extern void current_list_append_list(tree_node_list *the_list)  {    assert(curr_list != NULL);    curr_list->append(the_list);    delete the_list;  }/* *  This procedure is called on the suif procedure just before it is written *  out.  It acts as a final pass to figure out symbols that have their *  addresses taken; replace load-store combinations with memcpy's; change one *  step conversions between integers that change both the the size and sign to *  two different conversions; and replace a series of array reference *  instructions into a single multi-dimensional array reference instruction. *  Then it makes all the substitutions specified by global_replacements to *  merge types that are really the same in SUIF. */static void finalize_suif_proc(proc_sym *the_proc)  {    assert(the_proc != NULL);    tree_block *the_block = the_proc->block();    assert(the_block != NULL);    the_block->map(&finalize_suif_node, NULL);    (void)(the_block->clone_helper(global_replacements, TRUE));  }static void finalize_suif_node(tree_node *the_node, void *)  {    assert(the_node != NULL);    if (the_node->is_instr())      {        tree_instr *the_tree_instr = (tree_instr *)the_node;        the_tree_instr->instr_map(&finalize_suif_instr, NULL, FALSE);      }  }static void finalize_suif_instr(instruction *the_instr, void *)  {    assert(the_instr != NULL);    if (the_instr->opcode() == io_ldc)      {        in_ldc *the_ldc = (in_ldc *)the_instr;        immed value = the_ldc->value();        if (value.is_symbol())          {            sym_node *symbol = value.symbol();            assert(symbol != NULL);            if (symbol->is_var())              {                var_sym *the_var = (var_sym *)symbol;                the_var->set_addr_taken();              }          }      }    else if (the_instr->opcode() == io_str)      {        in_rrr *the_store = (in_rrr *)the_instr;        operand data_op = the_store->src2_op();        if (data_op.is_expr() && (data_op.instr()->opcode() == io_lod))          {            in_rrr *the_load = (in_rrr *)(data_op.instr());            operand source_address = the_load->src_addr_op();            source_address.remove();            data_op.remove();            the_store->set_opcode(io_memcpy);            the_store->set_src2(source_address);            delete the_load;          }      }    else if (the_instr->opcode() == io_cvt)      {        in_rrr *the_cvt = (in_rrr *)the_instr;        type_node *old_type = the_cvt->src_op().type()->unqual();        type_node *new_type = the_cvt->result_type()->unqual();        /*         *  If there is a convert from an int or pointer type to an int or         *  pointer type of a different size and one is signed but the other         *  isn't (pointers are treated as unsigned), SUIF needs two separate         *  convert instructions, one to change the size and one to change         *  between signed and unsigned.  It matters which order this         *  conversion is done:         *         *    - Going from an unsigned to a larger signed, everything         *      representable in the original type is representable in the new         *      type, so we just have to make sure it's representable in the         *      intermediate type.  It is representable in the larger         *      unsigned, so we can do that conversion first.  The other order         *      would not work; for example, converting 255 from an unsigned         *      char to a signed char would give -1, and converting that to a         *      signed int would give -1, not the correct 255.  So in this         *      case we must do the size conversion first.         *         *    - Going from a signed to a larger unsigned, 6.2.1.2, paragraph 2         *      of ANSI/ISO 9899-1990 clearly states that the value is first         *      promoted to the signed type of the larger size.  So we need to         *      do the size conversion first in this case, too.         *         *    - Going from a signed to a smaller unsigned, 6.2.1.2,         *      paragraph 3, sentence 1 or ANSI/ISO 9899-1990 defines the         *      result: it must be the remainder on division of the number of         *      values representable by the target type.  Converting first to         *      an unsigned type of the larger size and then to the smaller         *      size guarantees this will happen: it is the remainder on         *      division by the number of values representable by the smaller         *      unsigned of the remainder on division by the number of values         *      representable by the larger unsigned of the original value.         *      Since both numbers of values are powers of two, the larger is         *      a multiple of the smaller, so the result is what we needed.         *      So no matter how conversion to a smaller integer is defined         *      (the second sentence of paragraph 3 of 6.2.1.2 of         *      ANSI/ISO 9899-1990 makes it implementation defined), the result         *      is correct if we first do the sign conversion in this case.         *         *    - Going from an unsigned to a smaller signed is a bit more         *      problematic because the standard leaves this implementation         *      defined.  Anything representable in both types would also be         *      representable in the intermediate type either way the         *      conversion is done.  And most of the time we're in 2's         *      complement and changing between unsigned and signed leaves the         *      same bits and changing to a smaller size just throws away the         *      higher order bits, whether we are seeing it as a signed or         *      unsigned.  So it really doesn't matter much which way we         *      define it.         *      A reasonable assumption to make would be that any conversion         *      from a type A to a type B followed by a conversion from B to A         *      always gives back the original value if B has at least as many         *      bits as B.  Lets assume this is true of the conversion between         *      a signed and an unsigned with the same number of bits.  Then         *      we can guarantee this holds all the time if and only if we         *      choose to do the sign conversion first for the case of an         *      unsigned to a smaller signed.  So we'll do the sign conversion         *      first in this case.         *         *  The net result is that we want to do the size conversion first         *  when going to a larger size and the sign conversion first when         *  going to a smaller size.         */        if (((old_type->op() == TYPE_INT) || old_type->is_enum() ||             old_type->is_ptr()) &&            ((new_type->op() == TYPE_INT) || new_type->is_enum() ||             new_type->is_ptr()))          {            boolean old_signed = !non_negative(old_type);            boolean new_signed = !non_negative(new_type);            if ((new_signed != old_signed) &&                (new_type->size() != old_type->size()))              {                type_node *intermediate_type;                if (new_type->size() > old_type->size())                  {                    intermediate_type =                            new base_type(TYPE_INT, new_type->size(),                                          old_signed);                  }                else                  {                    intermediate_type =                            new base_type(TYPE_INT, old_type->size(),                                          new_signed);                  }                intermediate_type =                        fileset->globals()->install_type(intermediate_type);                operand old_op = the_cvt->src_op();                old_op.remove();                instruction *new_instr =                        new in_rrr(io_cvt, intermediate_type, operand(),                                   old_op);                the_cvt->set_src(operand(new_instr));              }          }        /*         *  Mgen also can't handle direct converts between floating point and         *  integers of any size other than word size.  So we need to go         *  through that size first.         */        else if (((old_type->op() == TYPE_FLOAT) &&                  ((new_type->op() == TYPE_INT) || new_type->is_enum()) &&                  (new_type->size() != type_signed->size())) ||                 ((new_type->op() == TYPE_FLOAT) &&                  ((old_type->op() == TYPE_INT) || old_type->is_enum()) &&                  (old_type->size() != type_signed->size())))          {            type_node *intermediate_type;            if ((old_type->op() == TYPE_INT) || old_type->is_enum())              {                if (non_negative(old_type))                    intermediate_type = type_unsigned;                else                    intermediate_type = type_signed;              }            else              {                if (non_negative(new_type))                    intermediate_type = type_unsigned;                else                    intermediate_type = type_signed;              }            operand old_op = the_cvt->src_op();            old_op.remove();            instruction *new_instr =                    new in_rrr(io_cvt, intermediate_type, operand(), old_op);            the_cvt->set_src(operand(new_instr));          }      }    else if (the_instr->opcode() == io_array)      {        in_array *the_array = (in_array *)the_instr;        operand base_operand = the_array->base_op();        if (base_operand.is_expr() &&            (base_operand.instr()->opcode() == io_array) &&            (base_operand.instr()->peek_annote(k_fields) == NULL))          {            /*             *  Collapse adjacent array references into a single array             *  reference instruction with multiple dimensions.             */            in_array *second_array = (in_array *)(base_operand.instr());            second_array->remove();            assert(the_array->dims() == 1);            unsigned new_num_dims = 1 + second_array->dims();            the_array->set_dims(new_num_dims);            assert(second_array->offset_op() == operand());            assert(second_array->offset() == 0);            operand last_index = the_array->index(0);            operand last_bound = the_array->bound(0);            last_index.remove();            last_bound.remove();            the_array->set_index(new_num_dims - 1, last_index);            the_array->set_bound(new_num_dims - 1, last_bound);            for (unsigned dim_num = 0; dim_num < new_num_dims - 1; ++dim_num)              {                operand this_index = second_array->index(dim_num);                operand this_bound = second_array->bound(dim_num);                this_index.remove();                this_bound.remove();                the_array->set_index(dim_num, this_index);                the_array->set_bound(dim_num, this_bound);              }            operand second_base = second_array->base_op();            second_base.remove();            the_array->set_base_op(second_base);            delete second_array;          }      }  }static annote *make_line_annote(Coordinate *location)  {    annote *result = new annote(k_line);    result->immeds()->append(immed((int)location->y));    result->immeds()->append(immed(location->file ? location->file : (char *)""));    return result;  }

⌨️ 快捷键说明

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