| #define DECLARE_ARRAY(A) array##A[0x10] |
| #define DECLARE_COUNTER(A) counter##A = 0 |
| #define DECLARE_POINTER(A) *pointer##A = array##A + x |
| /* Create a loop that allows post-modification of pointerA, followed by |
| a use of the post-modified address. */ |
| #define BEFORE(A) counter##A += *pointer##A, pointer##A += 3 |
| #define AFTER(A) counter##A += pointer##A[x] |
| |
| /* Set up the arrays so that one iteration of the loop sets the counter |
| to 3.0f. */ |
| #define INIT_ARRAY(A) array##A[1] = 1.0f, array##A[5] = 2.0f |
| |
| /* Check that the loop worked correctly for all values. */ |
| #define CHECK_ARRAY(A) exit_code |= (counter##A != 3.0f) |
| |
| /* Having 6 copies triggered the bug for ARM and Thumb. */ |
| #define MANY(A) A (0), A (1), A (2), A (3), A (4), A (5) |
| |
| /* Each addendA should be allocated a register. */ |
| #define INIT_VOLATILE(A) addend##A = vol |
| #define ADD_VOLATILE(A) vol += addend##A |
| |
| /* Having 5 copies triggered the bug for ARM and Thumb. */ |
| #define MANY2(A) A (0), A (1), A (2), A (3), A (4) |
| |
| float MANY (DECLARE_ARRAY); |
| float MANY (DECLARE_COUNTER); |
| |
| volatile int stop = 1; |
| volatile int vol; |
| |
| void __attribute__((noinline)) |
| foo (int x) |
| { |
| float MANY (DECLARE_POINTER); |
| int i; |
| |
| do |
| { |
| MANY (BEFORE); |
| MANY (AFTER); |
| /* Create an inner loop that should ensure the code above |
| has registers free for reload inheritance. */ |
| { |
| int MANY2 (INIT_VOLATILE); |
| for (i = 0; i < 10; i++) |
| MANY2 (ADD_VOLATILE); |
| } |
| } |
| while (!stop); |
| } |
| |
| int |
| main (void) |
| { |
| int exit_code = 0; |
| |
| MANY (INIT_ARRAY); |
| foo (1); |
| MANY (CHECK_ARRAY); |
| return exit_code; |
| } |