#ifdef HAVE_CONFIG_H #include #endif #include #include 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 ); }