summaryrefslogtreecommitdiff
path: root/tests/tst-immediate-exactness.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tst-immediate-exactness.c')
-rw-r--r--tests/tst-immediate-exactness.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/tests/tst-immediate-exactness.c b/tests/tst-immediate-exactness.c
new file mode 100644
index 0000000..ed054e7
--- /dev/null
+++ b/tests/tst-immediate-exactness.c
@@ -0,0 +1,100 @@
+#include <stdio.h>
+#include <string.h>
+#include <libmcpu.h>
+#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 );
+}