#include #include #include #include "../utils/mcpu-asm.h" #define CHECK(c,m) do { if(!(c)) { fprintf(stderr,"FAIL: %s\n",m); return 1; } } while(0) static int rejected( const char *src, const char *needle ) { cpu_asm_image im; char err[512]; int rc = cpu_assemble_text( src, &im, err, sizeof( err ) ); if( rc == 0 ) { cpu_asm_image_free( &im ); return( 0 ); } return( strstr( err, needle ) != 0 ); } int main( void ) { cpu_asm_image im; char err[512]; static const char *prec = "3.14243987129849274029174912694696912849214e-286"; char src[4096]; __cpu_init(); CHECK( cpu_assemble_text( ".text\nLDR r32@0x00000, -17.0\nHALT\n", &im, err, sizeof( err ) ) == 0, "exact real32 LDR accepted"); cpu_asm_image_free( &im ); CHECK( cpu_assemble_text( ".text\nLDR r4096@0x00000, 2.0\nHALT\n", &im, err, sizeof( err ) ) == 0, "exact real64 immediate widened to real4096 accepted"); cpu_asm_image_free( &im ); CHECK( rejected( ".text\nLDR r32@0x00000, 0.1\nHALT\n", "LDR immediate is not exactly representable as real32;"), "inexact real32 immediate rejected"); CHECK( rejected( ".text\nLDR r64@0x00000, 0.1\nHALT\n", "LDR immediate is not exactly representable as real64;"), "inexact real64 immediate rejected"); snprintf( src, sizeof( src ), ".text\nLDR r64@0x00000, %s\nHALT\n", prec ); CHECK( rejected( src, "LDR immediate is not exactly representable as real64;" ), "inexact real64 immediate rejected"); snprintf( src, sizeof( src ), ".text\nLDR r4096@0x00000, %s\nHALT\n", prec ); CHECK( rejected( src, "LDR immediate is not exactly representable as real64;" ), "wide LDR cannot hide binary64 precision loss"); CHECK( cpu_assemble_text( ".text\nLDC c64@0x00000, -17.0r0+32.0j0\nHALT\n", &im, err, sizeof( err ) ) == 0, "exact complex64 immediate accepted"); cpu_asm_image_free( &im ); CHECK( rejected( ".text\nLDC c128@0x00000, 0.1r0+32.0j0\nHALT\n", "LDC immediate component is not exactly representable as real32;"), "inexact complex immediate component rejected"); CHECK( rejected( ".text\nLDC c32@0x00000, 1.0r0+2.0j0\nHALT\n", "bad LDC destination"), "complex destination below 64 bits rejected"); CHECK( rejected( ".text\nLDI r128@0x00000, 9223372036854775808\nHALT\n", "LDI immediate is not exactly representable as integer64;"), "integer wider than signed IMM64 rejected"); CHECK( rejected( ".text\nLDI r8@0x00000, 255\nHALT\n", "LDI immediate is not exactly representable as integer8;"), "narrow integer immediate that changes value rejected"); CHECK( cpu_assemble_text( ".text\nLDI r8@0x00000, -1\nHALT\n", &im, err, sizeof( err ) ) == 0, "exact signed integer8 immediate accepted"); cpu_asm_image_free( &im ); snprintf( src, sizeof( src ), ".data\n" ".align 16\n" "wide_real:\n" " .real 4096, %s\n" "wide_int:\n" " .integer 128, 9223372036854775808\n" "wide_complex:\n" " .complex 4096, %s, -%s\n" ".text\n" " LOAD r4096@0x00000, wide_real\n" " LOAD r128@0x00200, wide_int\n" " LOAD c4096@0x00400, wide_complex\n" " HALT\n", prec, prec, prec); CHECK( cpu_assemble_text( src, &im, err, sizeof( err ) ) == 0, "DATA fallback with .real/.integer/.complex and LOAD accepted"); cpu_asm_image_free( &im ); __cpu_free_context(); puts( "libcpu immediate exactness regression: PASS" ); return( 0 ); }