authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-03-14 16:55:27+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-05 18:34:31-04:00
log2485f3004659723a1ccd2799a6e0bddb09e32d3b
treefdfe05021d1b7c57c80b14310e1ebeb28a639839
parent54ffcf95a8596aa3adf57cddbe079a24f849f408
signaturelock-open Commit is signed but in an unrecognized format.

ir: Support bitwise not on vectors


2 files changed, 59 insertions(+), 13 deletions(-)

src/ir.cpp+34-13
...@@ -20363,24 +20363,45 @@ static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction)...@@ -20363,24 +20363,45 @@ static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction)
20363 if (type_is_invalid(expr_type))20363 if (type_is_invalid(expr_type))
20364 return ira->codegen->invalid_inst_gen;20364 return ira->codegen->invalid_inst_gen;
2036520365
20366 if (expr_type->id == ZigTypeIdInt) {20366 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ?
20367 if (instr_is_comptime(value)) {20367 expr_type->data.vector.elem_type : expr_type;
20368 ZigValue *target_const_val = ir_resolve_const(ira, value, UndefBad);
20369 if (target_const_val == nullptr)
20370 return ira->codegen->invalid_inst_gen;
2037120368
20372 IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type);20369 if (scalar_type->id != ZigTypeIdInt) {
20373 bigint_not(&result->value->data.x_bigint, &target_const_val->data.x_bigint,20370 ir_add_error(ira, &instruction->base.base,
20374 expr_type->data.integral.bit_count, expr_type->data.integral.is_signed);20371 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name)));
20375 return result;20372 return ira->codegen->invalid_inst_gen;
20373 }
20374
20375 if (instr_is_comptime(value)) {
20376 ZigValue *expr_val = ir_resolve_const(ira, value, UndefBad);
20377 if (expr_val == nullptr)
20378 return ira->codegen->invalid_inst_gen;
20379
20380 IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type);
20381
20382 if (expr_type->id == ZigTypeIdVector) {
20383 expand_undef_array(ira->codegen, expr_val);
20384 result->value->special = ConstValSpecialUndef;
20385 expand_undef_array(ira->codegen, result->value);
20386
20387 for (size_t i = 0; i < expr_type->data.vector.len; i++) {
20388 ZigValue *src_val = &expr_val->data.x_array.data.s_none.elements[i];
20389 ZigValue *dst_val = &result->value->data.x_array.data.s_none.elements[i];
20390
20391 dst_val->type = scalar_type;
20392 dst_val->special = ConstValSpecialStatic;
20393 bigint_not(&dst_val->data.x_bigint, &src_val->data.x_bigint,
20394 scalar_type->data.integral.bit_count, scalar_type->data.integral.is_signed);
20395 }
20396 } else {
20397 bigint_not(&result->value->data.x_bigint, &expr_val->data.x_bigint,
20398 scalar_type->data.integral.bit_count, scalar_type->data.integral.is_signed);
20376 }20399 }
2037720400
20378 return ir_build_binary_not(ira, &instruction->base.base, value, expr_type);20401 return result;
20379 }20402 }
2038020403
20381 ir_add_error(ira, &instruction->base.base,20404 return ir_build_binary_not(ira, &instruction->base.base, value, expr_type);
20382 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name)));
20383 return ira->codegen->invalid_inst_gen;
20384}20405}
2038520406
20386static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *instruction) {20407static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *instruction) {
test/stage1/behavior/vector.zig+25
...@@ -351,3 +351,28 @@ test "vector division operators" {...@@ -351,3 +351,28 @@ test "vector division operators" {
351 S.doTheTest();351 S.doTheTest();
352 comptime S.doTheTest();352 comptime S.doTheTest();
353}353}
354
355test "vector bitwise not operator" {
356 const S = struct {
357 fn doTheTestNot(comptime T: type, x: @Vector(4, T)) void {
358 var y = ~x;
359 for (@as([4]T, y)) |v, i| {
360 expectEqual(~x[i], v);
361 }
362 }
363 fn doTheTest() void {
364 doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 });
365 doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 });
366 doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 });
367 doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 });
368
369 doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 });
370 doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 });
371 doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 });
372 doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 });
373 }
374 };
375
376 S.doTheTest();
377 comptime S.doTheTest();
378}