aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/go/gofrontend/types.cc54
-rw-r--r--gcc/go/gofrontend/types.h3
2 files changed, 47 insertions, 10 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 9423ef63276..f65dbd73c33 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -1580,6 +1580,42 @@ Type::make_type_descriptor_ptr_type()
return ret;
}
+// Return the alignment required by the memequalN function. N is a
+// type size: 16, 32, 64, or 128. The memequalN functions are defined
+// in libgo/go/runtime/alg.go.
+
+int64_t
+Type::memequal_align(Gogo* gogo, int size)
+{
+ const char* tn;
+ switch (size)
+ {
+ case 16:
+ tn = "int16";
+ break;
+ case 32:
+ tn = "int32";
+ break;
+ case 64:
+ tn = "int64";
+ break;
+ case 128:
+ // The code uses [2]int64, which must have the same alignment as
+ // int64.
+ tn = "int64";
+ break;
+ default:
+ go_unreachable();
+ }
+
+ Type* t = Type::lookup_integer_type(tn);
+
+ int64_t ret;
+ if (!t->backend_type_align(gogo, &ret))
+ go_unreachable();
+ return ret;
+}
+
// Return whether this type needs specially built type functions.
// This returns true for types that are comparable and either can not
// use an identity comparison, or are a non-standard size.
@@ -1614,14 +1650,13 @@ Type::needs_specific_type_functions(Gogo* gogo)
case 0:
case 1:
case 2:
- return align < 2;
+ return align < Type::memequal_align(gogo, 16);
case 4:
- return align < 4;
+ return align < Type::memequal_align(gogo, 32);
case 8:
- return align < 8;
+ return align < Type::memequal_align(gogo, 64);
case 16:
- // 8, not 16, because of how runtime.memequal128 is written.
- return align < 8;
+ return align < Type::memequal_align(gogo, 128);
default:
return true;
}
@@ -1713,7 +1748,7 @@ Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype,
equal_fnname = "runtime.memequal8";
break;
case 2:
- if (align < 2)
+ if (align < Type::memequal_align(gogo, 16))
build_functions = true;
else
{
@@ -1722,7 +1757,7 @@ Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype,
}
break;
case 4:
- if (align < 4)
+ if (align < Type::memequal_align(gogo, 32))
build_functions = true;
else
{
@@ -1731,7 +1766,7 @@ Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype,
}
break;
case 8:
- if (align < 8)
+ if (align < Type::memequal_align(gogo, 64))
build_functions = true;
else
{
@@ -1740,8 +1775,7 @@ Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype,
}
break;
case 16:
- // 8, not 16, because of how runtime.memequal128 is written.
- if (align < 8)
+ if (align < Type::memequal_align(gogo, 128))
build_functions = true;
else
{
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index a2a6e611cc8..47a70fcd08f 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -993,6 +993,9 @@ class Type
const std::string& equal_name,
Function_type* equal_fntype);
+ // Return the alignment required by the memequalN function.
+ static int64_t memequal_align(Gogo*, int size);
+
// Export the type.
void
export_type(Export* exp) const