#ifdef HAVE_CONFIG_H #include #endif #include #include #include __mpu_size_t __cpu_reg_size( unsigned int bits ) { if( bits < 8 || bits > 65536 || ( bits & ( bits - 1 ) ) ) return( 0 ); return( (__mpu_size_t)( bits >> 3 ) ); } int __cpu_reg_valid( unsigned int bits, __mpu_uint32_t a ) { __mpu_size_t n = __cpu_reg_size( bits ); if( !n ) return( 0 ); if( ( a & ( n - 1 ) ) != 0 ) return( 0 ); if( a > CPU_REGISTER_ADDRESS_MAX ) return( 0 ); if( (__mpu_uint64_t)a + n > CPU_REGISTERS_MEM_SIZE_IN_UNITS ) return( 0 ); return( 1 ); } __mpu_UNIT_t * __cpu_reg_ptr( unsigned int bits, __mpu_uint32_t a ) { return( __cpu_reg_valid( bits, a ) ? &__REGS[a] : (__mpu_UNIT_t *)0 ); } int __cpu_encode_reg24( __mpu_UNIT_t out[3], const cpu_register *r ) { unsigned int code = 0, b; if( !out || !r || !__cpu_reg_valid( r->bits, r->address ) ) return( -1 ); b = r->bits; while( b > 8 ) { b >>= 1; ++code; } if( code > 13 ) return( -1 ); out[0] = (__mpu_UNIT_t)( ( code << 4 ) | ( ( r->address >> 16 ) & 0x0f ) ); out[1] = (__mpu_UNIT_t)( ( r->address >> 8 ) & 0xff ); out[2] = (__mpu_UNIT_t)( r->address & 0xff ); return( 0 ); } int __cpu_decode_reg24( cpu_register *r, const __mpu_UNIT_t in[3] ) { unsigned int code; __mpu_uint32_t a; if( !r || !in ) return( -1 ); code = ( in[0] >> 4 ) & 0x0f; if( code > 13 ) return( -1 ); a = ( (__mpu_uint32_t)( in[0] & 0x0f ) << 16 ) | ( (__mpu_uint32_t)in[1] << 8 ) | in[2]; r->bits = 8U << code; r->address = a; return( __cpu_reg_valid( r->bits, a ) ? 0 : -1 ); } int __cpu_return_reg( cpu_register *r, unsigned int bits ) { __mpu_size_t n; if( !r ) return( -1 ); n = __cpu_reg_size( bits ); if( !n || (__mpu_uint64_t)n > CPU_RETURN_AREA_SIZE ) return( -1 ); r->bits = bits; r->address = (__mpu_uint32_t)( CPU_RETURN_AREA_END - (__mpu_uint32_t)n ); return( __cpu_reg_valid( r->bits, r->address ) ? 0 : -1 ); }