aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp62
1 files changed, 52 insertions, 10 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index cbc00f0cfe..e8ef45a116 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -25253,16 +25253,42 @@ static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstruct
}
static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstructionBswap *instruction) {
- ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child);
- if (type_is_invalid(int_type))
+ IrInstruction *op = instruction->op->child;
+ ZigType *type_expr = ir_resolve_type(ira, instruction->type->child);
+ if (type_is_invalid(type_expr))
return ira->codegen->invalid_instruction;
- IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type);
+ if (type_expr->id != ZigTypeIdInt) {
+ ir_add_error(ira, instruction->type,
+ buf_sprintf("expected integer type, found '%s'", buf_ptr(&type_expr->name)));
+ if (type_expr->id == ZigTypeIdVector &&
+ type_expr->data.vector.elem_type->id == ZigTypeIdInt)
+ ir_add_error(ira, instruction->type,
+ buf_sprintf("represent vectors with their scalar types, i.e. '%s'",
+ buf_ptr(&type_expr->data.vector.elem_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+ ZigType *int_type = type_expr;
+
+ ZigType *expr_type = op->value.type;
+ bool is_vector = expr_type->id == ZigTypeIdVector;
+ ZigType *ret_type = int_type;
+ if (is_vector)
+ ret_type = get_vector_type(ira->codegen, expr_type->data.vector.len, int_type);
+
+ op = ir_implicit_cast(ira, instruction->op->child, ret_type);
if (type_is_invalid(op->value.type))
return ira->codegen->invalid_instruction;
if (int_type->data.integral.bit_count == 0) {
- IrInstruction *result = ir_const(ira, &instruction->base, int_type);
+ IrInstruction *result = ir_const(ira, &instruction->base, ret_type);
+ if (is_vector) {
+ expand_undef_array(ira->codegen, &result->value);
+ result->value.data.x_array.data.s_none.elements =
+ allocate<ConstExprValue>(expr_type->data.vector.len);
+ for (unsigned i = 0; i < expr_type->data.vector.len; i++)
+ bigint_init_unsigned(&result->value.data.x_array.data.s_none.elements[i].data.x_bigint, 0);
+ }
bigint_init_unsigned(&result->value.data.x_bigint, 0);
return result;
}
@@ -25282,20 +25308,36 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
if (val == nullptr)
return ira->codegen->invalid_instruction;
if (val->special == ConstValSpecialUndef)
- return ir_const_undef(ira, &instruction->base, int_type);
+ return ir_const_undef(ira, &instruction->base, ret_type);
- IrInstruction *result = ir_const(ira, &instruction->base, int_type);
+ IrInstruction *result = ir_const(ira, &instruction->base, ret_type);
size_t buf_size = int_type->data.integral.bit_count / 8;
uint8_t *buf = allocate_nonzero<uint8_t>(buf_size);
- bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true);
- bigint_read_twos_complement(&result->value.data.x_bigint, buf, int_type->data.integral.bit_count, false,
- int_type->data.integral.is_signed);
+ if (is_vector) {
+ expand_undef_array(ira->codegen, &result->value);
+ result->value.data.x_array.data.s_none.elements =
+ allocate<ConstExprValue>(expr_type->data.vector.len);
+ for (unsigned i = 0; i < expr_type->data.vector.len; i++) {
+ ConstExprValue *cur = &val->data.x_array.data.s_none.elements[i];
+ result->value.data.x_array.data.s_none.elements[i].special = cur->special;
+ if (cur->special == ConstValSpecialUndef)
+ continue;
+ bigint_write_twos_complement(&cur->data.x_bigint, buf, int_type->data.integral.bit_count, true);
+ bigint_read_twos_complement(&result->value.data.x_array.data.s_none.elements[i].data.x_bigint,
+ buf, int_type->data.integral.bit_count, false,
+ int_type->data.integral.is_signed);
+ }
+ } else {
+ bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true);
+ bigint_read_twos_complement(&result->value.data.x_bigint, buf, int_type->data.integral.bit_count, false,
+ int_type->data.integral.is_signed);
+ }
return result;
}
IrInstruction *result = ir_build_bswap(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, nullptr, op);
- result->value.type = int_type;
+ result->value.type = ret_type;
return result;
}