multi_value cgs_sisd::cast_ints( multi_value const& v, cg_type* dest_tyi ) { builtin_types hint_src = v.hint(); builtin_types hint_dst = dest_tyi->hint(); builtin_types scalar_hint_src = scalar_of(hint_src); Type* dest_ty = dest_tyi->ty(v.abi()); Type* elem_ty = type_( scalar_of(hint_dst), abis::llvm ); cast_ops::id op = is_signed(scalar_hint_src) ? cast_ops::i2i_signed : cast_ops::i2i_unsigned; unary_intrin_functor cast_sv_fn = ext_->bind_cast_sv(elem_ty, op); value_array val = ext_->call_unary_intrin(dest_ty, v.load(), cast_sv_fn); return create_value( dest_tyi, builtin_types::none, val, value_kinds::value, v.abi() ); }
void cgs_sisd::switch_to( multi_value const& cond, std::vector< std::pair<multi_value, insert_point_t> > const& cases, insert_point_t const& default_branch ) { assert(parallel_factor_ == 1); Value* v = cond.load()[0]; SwitchInst* inst = builder().CreateSwitch( v, default_branch.block, static_cast<unsigned>(cases.size()) ); for( size_t i_case = 0; i_case < cases.size(); ++i_case ){ inst->addCase( llvm::cast<ConstantInt>( cases[i_case].first.load()[0] ), cases[i_case].second.block ); } }
multi_value cgs_sisd::cast_f2i( multi_value const& v, cg_type* dest_tyi ) { builtin_types hint_i = dest_tyi->hint(); builtin_types hint_f = v.hint(); EFLIB_UNREF_DECLARATOR(hint_f); builtin_types scalar_hint_i = scalar_of(hint_i); Type* dest_ty = dest_tyi->ty(v.abi()); Type* elem_ty = type_(scalar_hint_i, abis::llvm); cast_ops::id op = is_signed(hint_i) ? cast_ops::f2i : cast_ops::f2u; unary_intrin_functor cast_sv_fn = ext_->bind_cast_sv(elem_ty, op); value_array val = ext_->call_unary_intrin(dest_ty, v.load(), cast_sv_fn); return create_value( dest_tyi, builtin_types::none, val, value_kinds::value, v.abi() ); }
void cgs_sisd::emit_return( multi_value const& ret_v, abis::id abi ){ if( abi == abis::unknown ){ abi = fn().abi(); } if( fn().return_via_arg() ) { ext_->store( ret_v.load(abi), fn().return_address() ); builder().CreateRetVoid(); } else { Value* ret_value = NULL; if ( fn().multi_value_args() ) { ret_value = ext_->get_array( ret_v.load(abi) ); } else { ret_value = ret_v.load(abi)[0]; } builder().CreateRet(ret_value); } }
multi_value cgs_sisd::cast_f2b( multi_value const& v ) { assert( is_real(v.hint()) ); return emit_cmp_ne( v, null_value( v.hint(), v.abi() ) ); }
void cgs_sisd::store( multi_value& lhs, multi_value const& rhs ){ assert(parallel_factor_ == 1); value_array src(parallel_factor_, NULL); value_array address(parallel_factor_, NULL); value_kinds::id kind = lhs.kind(); if( kind == value_kinds::reference ){ src = rhs.load( lhs.abi() ); address = lhs.raw(); } else if ( kind == value_kinds::elements ){ elem_indexes indexes; multi_value const* root = NULL; bool is_swizzle = merge_swizzle(root, indexes, lhs); if( is_swizzle && is_vector( root->hint()) ){ assert( lhs.parent()->storable() ); multi_value rhs_rvalue = rhs.to_rvalue(); multi_value ret_v = root->to_rvalue(); for(size_t i = 0; i < vector_size(rhs.hint()); ++i) { ret_v = emit_insert_val( ret_v, indexes[i], emit_extract_val(rhs_rvalue, i) ); } src = ret_v.load( lhs.abi() ); address = root->load_ref(); } else { src = rhs.load( lhs.abi() ); address = lhs.load_ref(); } } assert( valid_all(src) ); assert( valid_all(address) ); ext_->store(src, address); }