summaryrefslogtreecommitdiff
path: root/tests/tst-immediate-exactness.c
blob: ed054e723aa875966495645a92268a3fc46d39e0 (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
#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 );
}