This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch,testsuite] Support dg-require-effective-target label_offsets.


On 26.10.2016 18:51, Bernd Schmidt wrote:
On 10/26/2016 04:46 PM, Georg-Johann Lay wrote:
+    if { [istarget avr-*-*] } {
+    # If the value of a label does not fit into 16 bits, the linker
+    # will generate a stub (containing a direct jump) and we end up
+    # with the address of the stub instead of the address of the very
+    # label.  Whereas it is legitimate to use such addresses for
+    # indirect jumps, it makes no sense to perform any arithmetic
+    # on such addresses.
+    return [check_no_compiler_messages label_offsets assembly {
+        #ifdef __AVR_3_BYTE_PC__
+        #error NO
+        #endif
+    }]
+    }
+    return 1;

I'm not sure I understand the failure mode. Sure, you're not getting the
address of the actual label, but the address of one that's equivalent - so why
can't you do arithmetic on it? Where does it go wrong?

There are devices where the address of a label does not fit into 16 bits, which is a problem for indirect calls because not all of the program memory can be targeted by 16 bits. The solution was to emit taking address of label LAB as gs(LAB) and let the linker resolve this ("gs" stands for "generate stub").

If LAB actually fits in 16 bits nothing special happens and we have LAB = gs(LAB).

If LAB doesn't fit then the linker generates a stub like:

gs_LAB:
   jump LAB

and resolves gs_LAB = gs(LAB). gs_LAB must be located in the lower part of the program memory so that gs_LAB will fit into 16 bits.

An indirect call / jump then is 1) take address of LAB which returns gs_LAB and 2) jump or call that address which jumps or calls gs_LAB which then jumps to LAB.

This works because absolute jumps and calls can target all of the program memory. Moreover comparing gs() labels against each other or against 0 for (un)equality will also work as expected.

Now imagine some arithmetic like &&LAB2 - &&LAB1. This might result in one or two stub addresses, and difference between such addresses is a complete different thing than the difference between the original labels: The result might differ in absolute value and in sign, i.e. you can't even determine whether LAB1 or LAB2 comes first in the generated code as the order of stubs might differ from the order of respective labels.

Am I right in thinking that only the execution test actually fails?

Bernd

Some of the run tests are failing, but not all of them. This is because gs() depends on code size and location. But there are also some compile tests that fail as avr_print_operand_address tries to warn about such code with "pointer offset from symbol maybe incorrect".

Johann


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]