📄 genop.cc
字号:
void genop::deallocate(void) { delete precomputation(); if (suif_operand().is_expr()) delete suif_operand().instr(); }void genop::clean_up_bit_field_refs(void) { precomputation()->map(&clean_field_refs_on_tree_node, NULL); the_suif_operand = clean_field_refs_on_operand(suif_operand()); }eval_status genop::evaluate_as_const(immed *result) { if (!precomputation()->is_empty()) return EVAL_NOT_CONST; suppress_array_folding = FALSE; eval_status status = evaluate_const_expr(suif_operand(), result); suppress_array_folding = TRUE; return status; }extern void init_annotes(void) { k_type_alignment = lexicon->enter("type alignment")->sp; ANNOTE(k_sequence_point, "sequence point", TRUE); ANNOTE(k_bit_field_info, "bit field info", FALSE); ANNOTE(k_type_name, "type name", FALSE); ANNOTE(k_type_source_coordinates, "type source coordinates", FALSE); ANNOTE(k_field_table, "field table", FALSE); ANNOTE(k_C_comment, "C comment", TRUE); ANNOTE(k_source_coordinates, "source coordinates", TRUE); ANNOTE(k_is_declared_reg, "is declared reg", FALSE); ANNOTE(k_source_references, "source references", TRUE); ANNOTE(k_builtin_args, "builtin args", TRUE); ANNOTE(k_typedef_name, "typedef name", TRUE); }extern void init_bit_ref(void) { /* Note that we don't install this since it will never be written out -- it's just a placeholder */ bit_ref_symbol = new proc_sym(func(inttype), src_unknown, "00bit_field_ref"); }extern tree_node *last_action_node(tree_node_list *the_node_list) { return last_action_before(the_node_list, NULL); }extern tree_node *last_action_before(tree_node_list *the_node_list, tree_node *the_node) { if (the_node_list == NULL) return NULL; if (the_node_list->is_empty()) return NULL; tree_node_list_e *current_element = the_node_list->tail(); if (the_node != NULL) { while (current_element != NULL) { tree_node_list_e *old_element = current_element; current_element = current_element->prev(); if (old_element->contents == the_node) break; } } while (current_element != NULL) { tree_node *this_node = current_element->contents; switch (this_node->kind()) { case TREE_INSTR: { tree_instr *the_tree_instr = (tree_instr *)this_node; instruction *the_instr = the_tree_instr->instr(); assert(the_instr != NULL); if ((the_instr->opcode() != io_mrk) && (the_instr->opcode() != io_nop)) { return this_node; } break; } case TREE_BLOCK: { tree_block *the_block = (tree_block *)this_node; tree_node *last_in_block = last_action_node(the_block->body()); if (last_in_block != NULL) return last_in_block; } default: return this_node; } current_element = current_element->prev(); } return NULL; }extern boolean operand_may_have_side_effects(operand the_operand) { if (the_operand.is_symbol()) { sym_node *the_symbol = the_operand.symbol(); assert(the_symbol != NULL); if (!the_symbol->is_var()) return TRUE; var_sym *the_var = (var_sym *)the_symbol; return any_part_volatile(the_var->type()); } else if (the_operand.is_expr()) { instruction *the_instr = the_operand.instr(); if (the_instr->opcode() == io_cal) { return TRUE; } else if (the_instr->opcode() == io_lod) { in_rrr *the_rrr = (in_rrr *)the_instr; operand address = the_rrr->src_addr_op(); type_node *addr_type = address.type(); addr_type = addr_type->unqual(); if (!addr_type->is_ptr()) return TRUE; ptr_type *the_ptr_type = (ptr_type *)addr_type; if (any_part_volatile(the_ptr_type->ref_type())) return TRUE; } else if (the_instr->opcode() == io_str) { return TRUE; } else if (the_instr->opcode() == io_memcpy) { return TRUE; } int num_srcs = the_instr->num_srcs(); for (int src_num = 0; src_num < num_srcs; ++src_num) { if (operand_may_have_side_effects(the_instr->src_op(src_num))) return TRUE; } return FALSE; } else if (the_operand.is_null()) { return FALSE; } else { return TRUE; } }extern boolean is_same_operand(operand op1, operand op2) { if (op1.is_symbol()) { if (!op2.is_symbol()) return FALSE; return (op1.symbol() == op2.symbol()); } else if (op1.is_expr()) { if (!op2.is_expr()) return FALSE; instruction *instr1 = op1.instr(); instruction *instr2 = op2.instr(); assert(instr1 != NULL); assert(instr2 != NULL); if (instr1->opcode() != instr2->opcode()) return FALSE; if (!instr1->result_type()->is_same(instr2->result_type())) return FALSE; if (instr1->opcode() == io_ldc) { in_ldc *ldc1 = (in_ldc *)instr1; in_ldc *ldc2 = (in_ldc *)instr2; return (ldc1->value() == ldc2->value()); } else { unsigned num_srcs = instr1->num_srcs(); if (num_srcs != instr2->num_srcs()) return FALSE; for (unsigned src_num = 0; src_num < num_srcs; ++src_num) { if (!is_same_operand(instr1->src_op(src_num), instr2->src_op(src_num))) { return FALSE; } } return TRUE; } } else { return FALSE; } }extern void comment_text(char *comment_string) { if (!option_keep_comments) return; suif_object *mark_object; if (curr_list == NULL) { mark_object = outf; } else { in_rrr *new_mark = new in_rrr(io_mrk); curr_list->append(new tree_instr(new_mark)); mark_object = new_mark; } immed_list *new_annote = new immed_list; new_annote->append(immed(comment_string)); mark_object->append_annote(k_C_comment, new_annote); }extern immed_list *coordinate_to_immeds(Coordinate the_coordinate) { immed_list *result = new immed_list; result->append(immed((the_coordinate.file == NULL) ? (char *) "" : the_coordinate.file)); result->append(immed((int)the_coordinate.x)); result->append(immed((int)the_coordinate.y)); return result; }extern Coordinate *immeds_to_coordinate(immed_list *the_immeds) { static Coordinate result; if (the_immeds == NULL) return NULL; immed_list_iter the_iter(the_immeds); if (the_iter.is_empty()) return NULL; immed file_immed = the_iter.step(); if (!file_immed.is_string()) return NULL; result.file = file_immed.string(); if (the_iter.is_empty()) return NULL; immed x_immed = the_iter.step(); if (!x_immed.is_integer()) return NULL; result.x = x_immed.integer(); if (the_iter.is_empty()) return NULL; immed y_immed = the_iter.step(); if (!y_immed.is_integer()) return NULL; result.y = y_immed.integer(); if (!the_iter.is_empty()) return NULL; return &result; }extern void remove_unused_temps(tree_node_list *the_list) { assert(the_list != NULL); sym_node_list unused; written_and_not_read(&unused, the_list); remove_writes(&unused, the_list); remove_symbols(&unused); sym_node_list read_once; find_temps_read_once(&read_once, the_list); attempt_combination(&read_once, the_list); while (!read_once.is_empty()) { sym_node_list_e *this_element = read_once.head(); read_once.remove(this_element); delete this_element; } }extern immed immed_and_type_for_C_intconst(char *C_intconst, type_node **the_type) { char *digit_start = C_intconst; int radix; if (*digit_start == '0') { ++digit_start; if ((*digit_start == 'X') || (*digit_start == 'x')) { ++digit_start; radix = 16; } else { radix = 8; } } else { radix = 10; } i_integer const_value(digit_start, radix); immed result_value = ii_to_immed(const_value); if (the_type != NULL) { char *follow = digit_start; while (TRUE) { if (((*follow >= '0') && (*follow <= '9')) || ((*follow >= 'a') && (*follow <= 'f')) || ((*follow >= 'A') && (*follow <= 'F'))) { ++follow; } else { break; } } int l_count = 0; boolean u_suffix = FALSE; while (TRUE) { if ((!u_suffix) && ((*follow == 'u') || (*follow == 'U'))) u_suffix = TRUE; else if ((l_count < 2) && ((*follow == 'l') || (*follow == 'L'))) ++l_count; else break; ++follow; } /* * See ANSI/ISO 9899-1990, section 6.1.3.2, second paragraph * of ``Semantics'' section. */ if ((l_count == 2) && u_suffix) { *the_type = unsignedlonglong; } else if (l_count == 2) { if (immed_fits(result_value, longlong)) *the_type = longlong; else *the_type = unsignedlonglong; } else if ((l_count >= 1) && u_suffix) { if (immed_fits(result_value, unsignedlong)) *the_type = unsignedlong; else *the_type = unsignedlonglong; } else if (l_count >= 1) { if (immed_fits(result_value, longtype))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -