There are targets that support taking values of labels but where any arithmetic on such values might produce garbage.

This patch introduces new dg-require-effective-target label_offsets which is a subset of label_values, and adjusts respective test cases to the more restricted predicate.

Run tests against avr-unknown-none ATmega2560 where it makes actually a difference between label_values and label_offsets.

Ok for trunk?

Johann

gcc/testsuite/
        * lib/target-supports.exp (check_effective_target_label_offsets):
        New proc.
        * gcc.dg/20021029-1.c (dg-require-effective-target): Require
        more restrict label_offsets instead of label_values.
        * gcc.dg/pr16973.c: Dito.
        * gcc.dg/torture/pr66123.c: Dito.
        * gcc.dg/torture/pr66178.c: Dito.
        * gcc.c-torture/compile/20021108-1.c: Dito.
        * gcc.c-torture/compile/920501-7.c: Dito.
        * gcc.c-torture/compile/labels-2.c: Dito.
        * gcc.c-torture/compile/labels-3.c: Dito.
        * gcc.c-torture/execute/pr70460.c: Dito.
Index: gcc.c-torture/compile/20021108-1.c
===================================================================
--- gcc.c-torture/compile/20021108-1.c	(revision 241546)
+++ gcc.c-torture/compile/20021108-1.c	(working copy)
@@ -1,4 +1,4 @@
-/* { dg-require-effective-target label_values } */
+/* { dg-require-effective-target label_offsets } */
 
 int
 main()
Index: gcc.c-torture/compile/920501-7.c
===================================================================
--- gcc.c-torture/compile/920501-7.c	(revision 241546)
+++ gcc.c-torture/compile/920501-7.c	(working copy)
@@ -1,3 +1,3 @@
-/* { dg-require-effective-target label_values } */
+/* { dg-require-effective-target label_offsets } */
 
 x(){if(&&e-&&b<0)x();b:goto*&&b;e:;}
Index: gcc.c-torture/compile/labels-2.c
===================================================================
--- gcc.c-torture/compile/labels-2.c	(revision 241546)
+++ gcc.c-torture/compile/labels-2.c	(working copy)
@@ -1,4 +1,4 @@
-/* { dg-require-effective-target label_values } */
+/* { dg-require-effective-target label_offsets } */
 
 struct bp { void *v, *b, *e; };
 f ()
Index: gcc.c-torture/compile/labels-3.c
===================================================================
--- gcc.c-torture/compile/labels-3.c	(revision 241546)
+++ gcc.c-torture/compile/labels-3.c	(working copy)
@@ -1,6 +1,6 @@
 /* Verify that we can narrow the storage associated with label diffs.  */
 /* { dg-require-effective-target indirect_jumps } */
-/* { dg-require-effective-target label_values } */
+/* { dg-require-effective-target label_offsets } */
 
 int foo (int a)
 {
Index: gcc.c-torture/execute/pr70460.c
===================================================================
--- gcc.c-torture/execute/pr70460.c	(revision 241546)
+++ gcc.c-torture/execute/pr70460.c	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-require-effective-target indirect_jumps } */
-/* { dg-require-effective-target label_values } */
+/* { dg-require-effective-target label_offsets } */
 
 /* PR rtl-optimization/70460 */
 
Index: gcc.dg/20021029-1.c
===================================================================
--- gcc.dg/20021029-1.c	(revision 241546)
+++ gcc.dg/20021029-1.c	(working copy)
@@ -3,7 +3,7 @@
 /* { dg-do compile { target fpic } } */
 /* { dg-options "-O2 -fpic" } */
 /* { dg-final { scan-assembler-not ".data.rel.ro.local" } } */
-/* { dg-require-effective-target label_values } */
+/* { dg-require-effective-target label_offsets } */
 /* { dg-require-effective-target indirect_jumps } */
 
 int foo (int a)
Index: gcc.dg/pr16973.c
===================================================================
--- gcc.dg/pr16973.c	(revision 241546)
+++ gcc.dg/pr16973.c	(working copy)
@@ -3,7 +3,7 @@
    to add back the label.   */
 
 /* { dg-options "" } */
-/* { dg-require-effective-target label_values } */
+/* { dg-require-effective-target label_offsets } */
 
 void
 f (void)
Index: gcc.dg/torture/pr66123.c
===================================================================
--- gcc.dg/torture/pr66123.c	(revision 241546)
+++ gcc.dg/torture/pr66123.c	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-require-effective-target label_values } */
+/* { dg-require-effective-target label_offsets } */
 
 int
 test (int foo)
Index: gcc.dg/torture/pr66178.c
===================================================================
--- gcc.dg/torture/pr66178.c	(revision 241546)
+++ gcc.dg/torture/pr66178.c	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-require-effective-target label_values } */
+/* { dg-require-effective-target label_offsets } */
 
 int test(void)
 {
Index: lib/target-supports.exp
===================================================================
--- lib/target-supports.exp	(revision 241546)
+++ lib/target-supports.exp	(working copy)
@@ -740,6 +740,31 @@ proc check_effective_target_label_values
     }]
 }
 
+# Return 1 if offsetting label values is supported, 0 otherwise.
+# A typical offset is the value of a different label like in
+# &&lab1 - &&lab2.
+
+proc check_effective_target_label_offsets {} {
+    # Offsetting labels implies we can take values of labels.
+    if { ![check_effective_target_label_values] } {
+	return 0;
+    }
+    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;
+}
+
 # Return 1 if builtin_return_address and builtin_frame_address are
 # supported, 0 otherwise.
 

Reply via email to