| ... | ... | @@ -15997,33 +15997,87 @@ static Stage1AirInst *ir_analyze_instruction_clz(IrAnalyze *ira, Stage1ZirInstCl |
| 15997 | 15997 | } |
| 15998 | 15998 | |
| 15999 | 15999 | static Stage1AirInst *ir_analyze_instruction_pop_count(IrAnalyze *ira, Stage1ZirInstPopCount *instruction) { |
| 16000 | Error err; |
| 16001 | |
| 16000 | 16002 | ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); |
| 16001 | 16003 | if (type_is_invalid(int_type)) |
| 16002 | 16004 | return ira->codegen->invalid_inst_gen; |
| 16003 | 16005 | |
| 16004 | | Stage1AirInst *op = ir_implicit_cast(ira, instruction->op->child, int_type); |
| 16006 | Stage1AirInst *uncasted_op = instruction->op->child; |
| 16007 | if (type_is_invalid(uncasted_op->value->type)) |
| 16008 | return ira->codegen->invalid_inst_gen; |
| 16009 | |
| 16010 | uint32_t vector_len = UINT32_MAX; // means not a vector |
| 16011 | if (uncasted_op->value->type->id == ZigTypeIdArray) { |
| 16012 | bool can_be_vec_elem; |
| 16013 | if ((err = is_valid_vector_elem_type(ira->codegen, uncasted_op->value->type->data.array.child_type, |
| 16014 | &can_be_vec_elem))) |
| 16015 | { |
| 16016 | return ira->codegen->invalid_inst_gen; |
| 16017 | } |
| 16018 | if (can_be_vec_elem) { |
| 16019 | vector_len = uncasted_op->value->type->data.array.len; |
| 16020 | } |
| 16021 | } else if (uncasted_op->value->type->id == ZigTypeIdVector) { |
| 16022 | vector_len = uncasted_op->value->type->data.vector.len; |
| 16023 | } |
| 16024 | |
| 16025 | bool is_vector = (vector_len != UINT32_MAX); |
| 16026 | ZigType *op_type = is_vector ? get_vector_type(ira->codegen, vector_len, int_type) : int_type; |
| 16027 | |
| 16028 | Stage1AirInst *op = ir_implicit_cast(ira, uncasted_op, op_type); |
| 16005 | 16029 | if (type_is_invalid(op->value->type)) |
| 16006 | 16030 | return ira->codegen->invalid_inst_gen; |
| 16007 | 16031 | |
| 16008 | 16032 | if (int_type->data.integral.bit_count == 0) |
| 16009 | 16033 | return ir_const_unsigned(ira, instruction->base.scope, instruction->base.source_node, 0); |
| 16010 | 16034 | |
| 16035 | ZigType *smallest_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); |
| 16036 | |
| 16011 | 16037 | if (instr_is_comptime(op)) { |
| 16012 | 16038 | ZigValue *val = ir_resolve_const(ira, op, UndefOk); |
| 16013 | 16039 | if (val == nullptr) |
| 16014 | 16040 | return ira->codegen->invalid_inst_gen; |
| 16015 | 16041 | if (val->special == ConstValSpecialUndef) |
| 16016 | 16042 | return ir_const_undef(ira, instruction->base.scope, instruction->base.source_node, ira->codegen->builtin_types.entry_num_lit_int); |
| 16043 | |
| 16044 | if (is_vector) { |
| 16045 | ZigType *smallest_vec_type = get_vector_type(ira->codegen, vector_len, smallest_type); |
| 16046 | Stage1AirInst *result = ir_const(ira, instruction->base.scope, instruction->base.source_node, smallest_vec_type); |
| 16047 | expand_undef_array(ira->codegen, val); |
| 16048 | result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(smallest_vec_type->data.vector.len); |
| 16049 | for (unsigned i = 0; i < smallest_vec_type->data.vector.len; i += 1) { |
| 16050 | ZigValue *op_elem_val = &val->data.x_array.data.s_none.elements[i]; |
| 16051 | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, instruction->base.source_node, |
| 16052 | op_elem_val, UndefOk))) |
| 16053 | { |
| 16054 | return ira->codegen->invalid_inst_gen; |
| 16055 | } |
| 16056 | ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; |
| 16057 | result_elem_val->type = smallest_type; |
| 16058 | result_elem_val->special = op_elem_val->special; |
| 16059 | if (op_elem_val->special == ConstValSpecialUndef) |
| 16060 | continue; |
| 16017 | 16061 | |
| 16018 | | if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { |
| 16019 | | size_t result = bigint_popcount_unsigned(&val->data.x_bigint); |
| 16062 | if (bigint_cmp_zero(&op_elem_val->data.x_bigint) != CmpLT) { |
| 16063 | size_t value = bigint_popcount_unsigned(&op_elem_val->data.x_bigint); |
| 16064 | bigint_init_unsigned(&result->value->data.x_array.data.s_none.elements[i].data.x_bigint, value); |
| 16065 | } |
| 16066 | size_t value = bigint_popcount_signed(&op_elem_val->data.x_bigint, int_type->data.integral.bit_count); |
| 16067 | bigint_init_unsigned(&result->value->data.x_array.data.s_none.elements[i].data.x_bigint, value); |
| 16068 | } |
| 16069 | return result; |
| 16070 | } else { |
| 16071 | if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { |
| 16072 | size_t result = bigint_popcount_unsigned(&val->data.x_bigint); |
| 16073 | return ir_const_unsigned(ira, instruction->base.scope, instruction->base.source_node, result); |
| 16074 | } |
| 16075 | size_t result = bigint_popcount_signed(&val->data.x_bigint, int_type->data.integral.bit_count); |
| 16020 | 16076 | return ir_const_unsigned(ira, instruction->base.scope, instruction->base.source_node, result); |
| 16021 | 16077 | } |
| 16022 | | size_t result = bigint_popcount_signed(&val->data.x_bigint, int_type->data.integral.bit_count); |
| 16023 | | return ir_const_unsigned(ira, instruction->base.scope, instruction->base.source_node, result); |
| 16024 | 16078 | } |
| 16025 | 16079 | |
| 16026 | | ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); |
| 16080 | ZigType *return_type = is_vector ? get_vector_type(ira->codegen, vector_len, smallest_type) : smallest_type; |
| 16027 | 16081 | return ir_build_pop_count_gen(ira, instruction->base.scope, instruction->base.source_node, return_type, op); |
| 16028 | 16082 | } |
| 16029 | 16083 | |