diff options
Diffstat (limited to 'tests/tst-overlap.c')
| -rw-r--r-- | tests/tst-overlap.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/tests/tst-overlap.c b/tests/tst-overlap.c new file mode 100644 index 0000000..9de9286 --- /dev/null +++ b/tests/tst-overlap.c @@ -0,0 +1,104 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> + +#include <libmcpu.h> + + +static int failures = 0; + +#define CHECK(cond,msg) \ + do { \ + if( !(cond) ) \ + { \ + fprintf( stderr, "FAIL: %s\n", (msg) ); \ + ++failures; \ + } \ + } while( 0 ) + + +int +main( void ) +{ + __mpu_UNIT_t *r64; + __mpu_UNIT_t *r32_0; + __mpu_UNIT_t *r32_4; + __mpu_UNIT_t *r16_2; + __mpu_UNIT_t *r8_3; + unsigned int i; + + __cpu_init(); + + r64 = __cpu_reg_ptr( 64, 0 ); + r32_0 = __cpu_reg_ptr( 32, 0 ); + r32_4 = __cpu_reg_ptr( 32, 4 ); + r16_2 = __cpu_reg_ptr( 16, 2 ); + r8_3 = __cpu_reg_ptr( 8, 3 ); + + CHECK( r64 != 0, "r64@0 pointer" ); + CHECK( r32_0 != 0, "r32@0 pointer" ); + CHECK( r32_4 != 0, "r32@4 pointer" ); + CHECK( r16_2 != 0, "r16@2 pointer" ); + CHECK( r8_3 != 0, "r8@3 pointer" ); + + CHECK( r64 == r32_0, "r64@0 and r32@0 start at same byte" ); + CHECK( r32_4 == r64 + 4, "r32@4 overlaps upper four bytes of r64@0" ); + CHECK( r16_2 == r64 + 2, "r16@2 overlaps bytes 2..3 of r64@0" ); + CHECK( r8_3 == r64 + 3, "r8@3 overlaps byte 3 of r64@0" ); + + for( i = 0; i < 8; ++i ) r64[i] = (__mpu_UNIT_t)( 0x10 + i ); + + CHECK( r32_0[0] == 0x10 && r32_0[1] == 0x11 && + r32_0[2] == 0x12 && r32_0[3] == 0x13, + "r32@0 sees bytes written through r64@0" ); + + CHECK( r32_4[0] == 0x14 && r32_4[1] == 0x15 && + r32_4[2] == 0x16 && r32_4[3] == 0x17, + "r32@4 sees bytes written through r64@0" ); + + CHECK( r16_2[0] == 0x12 && r16_2[1] == 0x13, + "r16@2 sees bytes written through r64@0" ); + + *r8_3 = 0xa5; + CHECK( r64[3] == 0xa5, + "write through r8@3 changes r64@0 storage" ); + CHECK( r32_0[3] == 0xa5, + "write through r8@3 changes r32@0 storage" ); + CHECK( r16_2[1] == 0xa5, + "write through r8@3 changes r16@2 storage" ); + + /* Check the same property at a non-zero naturally aligned address. */ + { + __mpu_UNIT_t *r128 = __cpu_reg_ptr( 128, 0x00100 ); + __mpu_UNIT_t *r32 = __cpu_reg_ptr( 32, 0x0010c ); + __mpu_UNIT_t *r8 = __cpu_reg_ptr( 8, 0x0010f ); + + CHECK( r128 != 0 && r32 != 0 && r8 != 0, + "overlap pointers at 0x00100" ); + CHECK( r32 == r128 + 12, + "r32@0x0010c inside r128@0x00100" ); + CHECK( r8 == r128 + 15, + "r8@0x0010f inside r128@0x00100" ); + + r128[15] = 0x5a; + CHECK( *r8 == 0x5a, + "r8 view sees r128 storage" ); + + r32[3] = 0xc3; + CHECK( r128[15] == 0xc3, + "r32 view changes r128 storage" ); + } + + if( failures != 0 ) + { + fprintf( stderr, "libcpu overlap regression: %d failure(s)\n", failures ); + return( 1 ); + } + + printf( "libcpu 0.0.3 overlapping register views regression: PASS\n" ); + printf( "overlap is byte-storage aliasing and is endian independent\n" ); + + return( 0 ); +} |
