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.