Commit 29386f0d30

LemonBoy <thatlemon@gmail.com>
2021-06-10 11:46:27
stage1: Fix handling of C ABI parameters split in multiple regs
Take into account the increased number of parameters when flattening a structure into one or more SSE registers. Fixes #9061
1 parent 80e1797
Changed files (3)
src
test
stage1
src/stage1/codegen.cpp
@@ -2161,11 +2161,11 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
             // Register 2: (ptr + 1).*
 
             // One floating point register per f64 or 2 f32's
-            size_t number_of_fp_regs = (size_t)ceilf((float)ty_size / (float)8);
+            size_t number_of_fp_regs = (ty_size + 7) / 8;
 
             switch (fn_walk->id) {
                 case FnWalkIdAttrs: {
-                    fn_walk->data.attrs.gen_i += 1;
+                    fn_walk->data.attrs.gen_i += number_of_fp_regs;
                     break;
                 }
                 case FnWalkIdCall: {
test/stage1/c_abi/cfuncs.c
@@ -1,6 +1,7 @@
 #include <inttypes.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <string.h>
 
 void zig_panic();
 
@@ -253,6 +254,13 @@ void c_small_struct_floats(Vector3 vec) {
     assert_or_panic(vec.z == 12.0);
 }
 
+void c_small_struct_floats_extra(Vector3 vec, const char *str) {
+    assert_or_panic(vec.x == 3.0);
+    assert_or_panic(vec.y == 6.0);
+    assert_or_panic(vec.z == 12.0);
+    assert_or_panic(!strcmp(str, "hello"));
+}
+
 void c_big_struct_floats(Vector5 vec) {
     assert_or_panic(vec.x == 76.0);
     assert_or_panic(vec.y == -1.0);
test/stage1/c_abi/main.zig
@@ -257,6 +257,7 @@ const Vector3 = extern struct {
     z: f32,
 };
 extern fn c_small_struct_floats(Vector3) void;
+extern fn c_small_struct_floats_extra(Vector3, ?[*]const u8) void;
 
 const Vector5 = extern struct {
     x: f32,
@@ -274,6 +275,7 @@ test "C ABI structs of floats as parameter" {
         .z = 12.0,
     };
     c_small_struct_floats(v3);
+    c_small_struct_floats_extra(v3, "hello");
 
     var v5 = Vector5{
         .x = 76.0,