static String handle_static_unary_expression(CPrintStyleModule *state, const SuifObject *obj) { UnaryExpression *expr = to<UnaryExpression>(obj); LString opc =expr->get_opcode(); String src_string = state->print_to_string(expr->get_source()); for (size_t i = 0; i < NUM_UNARY_OPER; i++ ) { if (*(unary_oper_table[i]._oper) == opc) { const char *op_char = unary_oper_table[i]._op_char; return(String("(") + op_char + src_string + ")"); } } // if (opc == &k_convert) { return(src_string); } if (opc == k_copy) { return(src_string); } return(String(opc) + "(" + src_string + ")"); }
/* Another helper function for print_var_def(). This function * expects that it will need to add a return before printing * anything, and it expects that you will add a return after * it is done. * It returns the number of bits of initialization data that it * generates. */ int PrinterX86::process_value_block(ValueBlock *vblk) { int bits_filled = 0; if (is_a<ExpressionValueBlock>(vblk)) { // An ExpressionValueBlock either holds a constant value or a // simple expression representing either an address relative to // a symbol or a pointer generated by conversion from an integer // constant (presumably zero). ExpressionValueBlock *evb = (ExpressionValueBlock*)vblk; Expression *exp = evb->get_expression(); if (is_a<IntConstant>(exp)) { IntConstant *ic = (IntConstant*)exp; bits_filled = print_size_directive(ic->get_result_type()); fprint(out, ic->get_value()); cur_opnd_cnt++; } else if (is_a<FloatConstant>(exp)) { FloatConstant *fc = (FloatConstant*)exp; bits_filled = print_size_directive(fc->get_result_type()); fputs(fc->get_value().c_str(), out); cur_opnd_cnt++; } else { // We use non-constant ExpressionValueBlocks to hold a symbolic // address, optionally with an offset, or a pointer initializer // consisting of a `convert' expression. // A SymbolAddressExpression represents a plain symbolic // address. // An address obtained by conversion from another type is a // unary expression with opcode "convert". // A symbol+delta is represented by an add whose first operand // is the load-address and whose second is an IntConstant // expression. // No other kind of "expression" is recognized. if (is_a<UnaryExpression>(exp)) { UnaryExpression *ux = (UnaryExpression*)exp; claim(ux->get_opcode() == k_convert, "unexpected unary expression in expression block"); DataType *tt = ux->get_result_type(); // target type claim(is_kind_of<PointerType>(tt), "unexpected target type when converting initializer"); exp = ux->get_source(); if (is_a<IntConstant>(exp)) { IntConstant *ic = (IntConstant*)exp; bits_filled = print_size_directive(tt); fprint(out, ic->get_value()); cur_opnd_cnt++; return bits_filled; } // Fall through to handle symbol-relative address, on the // assumption that the front end validated the conversion. } SymbolAddressExpression *sax; long delta; if (is_a<BinaryExpression>(exp)) { BinaryExpression *bx = (BinaryExpression*)exp; claim(bx->get_opcode() == k_add, "unexpected binary expression in expression block"); Expression *s1 = bx->get_source1(); Expression *s2 = bx->get_source2(); sax = to<SymbolAddressExpression>(s1); delta = to<IntConstant>(s2)->get_value().c_long(); } else if (is_a<SymbolAddressExpression>(exp)) { sax = (SymbolAddressExpression*)exp; delta = 0; } else { claim(false, "unexpected kind of expression block"); } Sym *sym = sax->get_addressed_symbol(); // symbol initialization bits_filled = print_size_directive(type_ptr); print_sym(sym); if (delta != 0) { fprintf(out, "%+ld", delta); } // always force the start of a new data directive cur_opcode = opcode_null; cur_opnd_cnt = 0; } } else if (is_a<MultiValueBlock>(vblk)) { MultiValueBlock *mvb = (MultiValueBlock*)vblk; for (int i = 0; i < mvb->get_sub_block_count(); i++ ) { int offset = mvb->get_sub_block(i).first.c_int(); claim(offset >= bits_filled); if (bits_filled < offset) // pad to offset bits_filled += print_bit_filler(offset - bits_filled); bits_filled += process_value_block(mvb->get_sub_block(i).second); } int all_bits = get_bit_size(mvb->get_type()); if (all_bits > bits_filled) bits_filled += print_bit_filler(all_bits - bits_filled); } else if (is_a<RepeatValueBlock>(vblk)) { // Simplifying assumption: We now expect the front-end // to remove initialization code of large arrays of zeros. RepeatValueBlock *rvb = (RepeatValueBlock*)vblk; int repeat_cnt = rvb->get_num_repetitions(); if (repeat_cnt > 1) { // insert .repeat pseudo-op fprintf(out, "\n\t%s\t%d", x86_opcode_names[REPEAT], repeat_cnt); cur_opcode = opcode_null; // force new data directive } // actual data directive bits_filled = repeat_cnt * process_value_block(rvb->get_sub_block()); if (repeat_cnt > 1) { // insert .endr pseudo-op fprintf(out, "\n\t%s", x86_opcode_names[ENDR]); cur_opcode = opcode_null; // force new data directive } } else if (is_a<UndefinedValueBlock>(vblk)) { bits_filled += print_bit_filler(get_bit_size(vblk->get_type())); } else { claim(false, "unexpected kind of ValueBlock"); } return bits_filled; }
void EliminateArrayConvertsPass::do_procedure_definition(ProcedureDefinition* proc_def){ suif_hash_map<ParameterSymbol*, Type*> params; TypeBuilder *tb = (TypeBuilder*) get_suif_env()->get_object_factory(TypeBuilder::get_class_name()); // collect all procedure parameters of pointer type into params list for(Iter<ParameterSymbol*> iter = proc_def->get_formal_parameter_iterator(); iter.is_valid(); iter.next()) { ParameterSymbol* par_sym = iter.current(); Type* par_type = tb->unqualify_type(par_sym->get_type()); if(is_kind_of<PointerType>(par_type)){ // put NULLs into the map at first, // they will later be overwritten params[par_sym] = NULL; } } if(params.size()==0) return; // nothing to do // walk thru all AREs and look for arrays that are in the param list {for(Iter<ArrayReferenceExpression> iter = object_iterator<ArrayReferenceExpression>(proc_def); iter.is_valid(); iter.next()) { ArrayReferenceExpression* are = &iter.current(); if(is_kind_of<UnaryExpression>(are->get_base_array_address())){ UnaryExpression* ue = to<UnaryExpression>(are->get_base_array_address()); if(ue->get_opcode() == k_convert){ if(is_kind_of<LoadVariableExpression>(ue->get_source())){ LoadVariableExpression* lve = to<LoadVariableExpression>(ue->get_source()); VariableSymbol* array = lve->get_source(); for(suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.begin(); iter!=params.end();iter++) { ParameterSymbol* par_sym = (*iter).first; if(par_sym == array){ // match! Type* array_type; suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.find(par_sym); if(iter==params.end() || (*iter).second==NULL){ //array_type = to<PointerType>(ue->get_result_type())->get_reference_type(); array_type = tb->get_qualified_type(ue->get_result_type()); params[par_sym] = array_type; //printf("%s has type ",par_sym->get_name().c_str()); //array_type->print_to_default(); }else{ array_type = params[par_sym].second; suif_assert(is_kind_of<QualifiedType>(array_type)); } array->replace(array->get_type(), array_type); remove_suif_object(ue); remove_suif_object(lve); lve->replace(lve->get_result_type(), tb->unqualify_type(array_type)); // put the LoadVar directly under ARE are->set_base_array_address(lve); //are->print_to_default(); } } } else { suif_warning(ue->get_source(), ("Expecting a LoadVariableExpression here")); } } else { suif_warning(ue, ("Disallow converts in AREs for " "things other than procedure parameters")); } } } } }