<div dir="ltr"><div dir="ltr">Small improvements inline:<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Dec 20, 2019 at 1:25 AM Sebastian Huber <<a href="mailto:sebastian.huber@embedded-brains.de" target="_blank">sebastian.huber@embedded-brains.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
while working on a test case for<br>
<br>
<a href="https://devel.rtems.org/ticket/3767" rel="noreferrer" target="_blank">https://devel.rtems.org/ticket/3767</a><br>
<br>
I tried to find the right test suite for it. At first I thought that <br>
this is a unit test <br>
(testsuites/unit/compiler/tc-misaligned-builtin-memcpy.c). However, I <br>
now think that we should have a requirement for this function. The test <br>
case is more or less clear:<br>
<br>
T_TEST_CASE(MisalignedBuiltinMemcpy)<br>
{<br>
double a;<br>
double b;<br>
char buf[2 * sizeof(double)];<br></blockquote><div><br></div><div>buf has the alignment of char. Although it is likely to be aligned to sizeof(int), it very well could be less than that. In C11 and newer, you can use alignas() to force buf to have the alignment of double.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
void *p;<br>
<br>
p = &buf[0]; </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> p = (void *)((uintptr_t)p | 1);<br></blockquote><div><br></div><div>IMO, this reads a bit clearer if p is just a char*. Then you would initialize it to the address of buf[1] to force the misalignment.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
RTEMS_OBFUSCATE_VARIABLE(p);<br>
a = 123e4;<br>
RTEMS_OBFUSCATE_VARIABLE(a);<br>
a *= a;<br>
memcpy(p, &a, sizeof(a));<br>
RTEMS_OBFUSCATE_VARIABLE(p);<br>
memcpy(&b, p, sizeof(b));<br>
T_eq(a, b, "%f == %f", a, b);<br>
}<br>
<br>
It is obvious that such a memcpy() operation should work. In general, we <br>
assume in RTEMS that the compiler does the right job. However, on some <br>
architectures we have to select the right compiler options and this is <br>
clearly under full control of the RTEMS BSP. I think we should add <br>
something like this to the RTEMS requirements:<br>
<br>
A call of memcpy() in C from a pointer to a double value to a misaligned <br>
destination buffer shall store the double value in the destination buffer.<br>
<br>
The formulation is quite specific, but I was not able to formulate it <br>
more generic and keep it testable.</blockquote><div><br></div><div>I've worked on at least one system where double's were silently equivalent to float. Maybe a sized integer type such as int64_t would be a better candidate for the test case?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">We have to keep in mind here that we <br>
are not interested in the memcpy() C library function, but rather the <br>
compiler optimized code for the memcpy() builtin function.<br></blockquote><div><br></div><div>This is going to be difficult to verify without examining the generated assembly code.</div><div><br></div><div>-mstrict-align would be overkill for some systems. At least on ARMv7 and ARMv8, many instructions do support unaligned accesses, while some other instructions don't.<br></div><br clear="all"></div>HTH,<br><div>-- <br><div dir="ltr">Jonathan Brandmeyer<br><br></div></div></div>