summaryrefslogtreecommitdiff
path: root/tests/tst-registers.c
blob: c8b1c99b2297a78650db7936371552955f9a60fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#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 )


struct width_test
{
  unsigned int bits;
  __mpu_size_t bytes;
};


int
main( void )
{
  static const struct width_test widths[] =
  {
    {     8,    1 },
    {    16,    2 },
    {    32,    4 },
    {    64,    8 },
    {   128,   16 },
    {   256,   32 },
    {   512,   64 },
    {  1024,  128 },
    {  2048,  256 },
    {  4096,  512 },
    {  8192, 1024 },
    { 16384, 2048 },
    { 32768, 4096 },
    { 65536, 8192 }
  };

  __mpu_size_t i;

  __cpu_init();

  CHECK( CPU_REGISTERS_MEM_SIZE_IN_UNITS == 524288,
         "512 KiB register file size" );
  CHECK( CPU_REGISTER_ADDRESS_MAX == 0x0007ffffU,
         "register address maximum" );
  CHECK( CPU_REGISTER_MIN_BITS == 8,
         "minimum register width" );
  CHECK( CPU_REGISTER_MAX_BITS == 65536,
         "maximum register width" );

  for( i = 0; i < sizeof( widths ) / sizeof( widths[0] ); ++i )
  {
    __mpu_uint32_t last;

    CHECK( __cpu_reg_size( widths[i].bits ) == widths[i].bytes,
           "register width size" );

    CHECK( __cpu_reg_valid( widths[i].bits, 0 ) == 1,
           "register at address zero" );

    CHECK( __cpu_reg_ptr( widths[i].bits, 0 ) == __cpu_registers,
           "register pointer at address zero" );

    last = (__mpu_uint32_t)(CPU_REGISTERS_MEM_SIZE_IN_UNITS - widths[i].bytes);

    CHECK( __cpu_reg_valid( widths[i].bits, last ) == 1,
           "last naturally aligned register" );

    CHECK( __cpu_reg_ptr( widths[i].bits, last ) == &__cpu_registers[last],
           "last register pointer" );

    if( widths[i].bytes > 1 )
    {
      CHECK( __cpu_reg_valid( widths[i].bits, last + 1 ) == 0,
             "natural alignment check" );
      CHECK( __cpu_reg_ptr( widths[i].bits, last + 1 ) == 0,
             "unaligned register pointer" );
    }
  }

  CHECK( __cpu_reg_size( 0 ) == 0, "zero register width" );
  CHECK( __cpu_reg_size( 7 ) == 0, "unsupported 7-bit register width" );
  CHECK( __cpu_reg_size( 24 ) == 0, "unsupported 24-bit register width" );
  CHECK( __cpu_reg_size( 131072 ) == 0, "register width above 65536" );

  CHECK( __cpu_reg_valid( 8, CPU_REGISTERS_MEM_SIZE_IN_UNITS - 1 ) == 1,
         "last byte is a valid r8" );
  CHECK( __cpu_reg_valid( 8, CPU_REGISTERS_MEM_SIZE_IN_UNITS ) == 0,
         "address one byte beyond register file" );
  CHECK( __cpu_reg_ptr( 8, CPU_REGISTERS_MEM_SIZE_IN_UNITS ) == 0,
         "pointer beyond register file" );

  CHECK( __cpu_reg_valid( 32, 12 ) == 1,
         "r32 naturally aligned address" );
  CHECK( __cpu_reg_valid( 32, 13 ) == 0,
         "r32 unaligned address" );

  CHECK( __cpu_reg_valid( 65536, 0x0007e000U ) == 1,
         "last r65536 region" );
  CHECK( __cpu_reg_valid( 65536, 0x0007e001U ) == 0,
         "unaligned r65536 region" );
  CHECK( __cpu_reg_valid( 65536, 0x00080000U ) == 0,
         "r65536 beyond register file" );

  if( failures != 0 )
  {
    fprintf( stderr, "libcpu register regression: %d failure(s)\n", failures );
    return( 1 );
  }

  printf( "libcpu 0.0.3 register width/alignment/bounds regression: PASS\n" );
  printf( "register widths: r8 ... r65536\n" );
  printf( "register address range: 0x00000 ... 0x7ffff\n" );

  return( 0 );
}