Commit 6235afc632

Veikka Tuominen <git@vexu.eu>
2022-02-17 16:29:19
stage1: fix f80 negation
1 parent f20929b
Changed files (2)
src
test
behavior
src/stage1/codegen.cpp
@@ -4139,13 +4139,9 @@ static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable,
 static LLVMValueRef ir_gen_soft_f80_neg(CodeGen *g, ZigType *op_type, LLVMValueRef operand) {
     uint32_t vector_len = op_type->id == ZigTypeIdVector ? op_type->data.vector.len : 0;
 
-    uint64_t buf[2] = {0, 0};
-    if (g->is_big_endian != native_is_big_endian) {
-        buf[1] = 0x8000000000000000;
-    } else {
-        buf[1] = 0x8000;
-    }
-    LLVMValueRef sign_mask = LLVMConstIntOfArbitraryPrecision(LLVMInt128Type(), 2, buf);
+    LLVMTypeRef llvm_i80 = LLVMIntType(80);
+    LLVMValueRef sign_mask = LLVMConstInt(llvm_i80, 1, false);
+    sign_mask = LLVMConstShl(sign_mask, LLVMConstInt(llvm_i80, 79, false));
 
     LLVMValueRef result;
     if (vector_len == 0) {
test/behavior/floatop.zig
@@ -448,3 +448,21 @@ fn testTrunc() !void {
         try expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon));
     }
 }
+
+test "negation" {
+    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+    if (builtin.os.tag == .freebsd) return error.SkipZigTest;
+
+    const S = struct {
+        fn doTheTest() !void {
+            inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
+                var a: T = 1;
+                a = -a;
+                try expect(a == -1);
+            }
+        }
+    };
+
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}