summaryrefslogtreecommitdiff
path: root/tests/tst-asm-directives.c
diff options
context:
space:
mode:
authorkx <kx@radix-linux.su>2026-10-09 18:00:15 +0300
committerkx <kx@radix-linux.su>2026-10-09 18:00:15 +0300
commit065da3509019b15dd0e678072e6be629e5330bef (patch)
tree69c934c9e786ac048b4fbe8f4c4c5571661521f4 /tests/tst-asm-directives.c
parentd130fe27fa753be02ed76fd9b277aa3c3d928eb9 (diff)
downloadlibmcpu-0.4.0.tar.xz
Version 0.4.00.4.0
Diffstat (limited to 'tests/tst-asm-directives.c')
-rw-r--r--tests/tst-asm-directives.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/tests/tst-asm-directives.c b/tests/tst-asm-directives.c
new file mode 100644
index 0000000..e86f46e
--- /dev/null
+++ b/tests/tst-asm-directives.c
@@ -0,0 +1,84 @@
+#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 const char src[] =
+".equ REG0, REGBASE+0\n"
+".equ REGBASE, 0x03000\n"
+".equ STEP, 4*512\n"
+".data\n"
+"ucs:\n"
+" .ucs2 \"Андрей\"\n"
+"utf:\n"
+" .utf8 \"Андрей\"\n"
+"raw:\n"
+" .byte 1, 2+3, STEP/512, 0xff\n"
+"ints:\n"
+" .integer 16, 0x0410, 0x043d, 0\n"
+"ints8:\n"
+" .int 8, 65, 66, 0\n"
+" .align 4*4\n"
+"vals:\n"
+" .integer 64, 11, 42\n"
+".text\n"
+"start:\n"
+" LDI r64@REG0, 40+2\n"
+" LOAD r64@(REG0+8), vals+8\n"
+" HALT\n";
+
+int
+main( void )
+{
+ cpu_asm_image im;
+ char err[256];
+ int rc, i;
+ static const __mpu_uint16_t ucs_expect[] =
+ {
+ 0x0410, 0x043d, 0x0434, 0x0440, 0x0435, 0x0439, 0
+ };
+ static const unsigned char utf_expect[] =
+ {
+ 0xd0, 0x90, 0xd0, 0xbd, 0xd0, 0xb4, 0xd1, 0x80, 0xd0, 0xb5, 0xd0, 0xb9, 0
+ };
+ static const unsigned char raw_expect[] =
+ {
+ 1, 5, 4, 0xff
+ };
+ static const char bad_ucs[] = ".data\n.ucs2 \"\\U0001F600\"\n.text\nHALT\n";
+ static const char bad_byte[] = ".data\n.byte 256\n.text\nHALT\n";
+ static const char bad_cycle[] = ".equ A, B+1\n.equ B, A+1\n.text\nHALT\n";
+
+ __cpu_init();
+ CHECK( cpu_assemble_text( src, &im, err, sizeof( err ) ) == 0, err );
+ CHECK( im.data_size == 80, "DATA size including NULL guard, strings, raw bytes, integer lists and alignment" );
+ for( i = 0; i < 7; i++ ) CHECK( __cpu_data_get_u16( im.data + 16 + i * 2 ) == ucs_expect[i], ".ucs2 code unit" );
+ CHECK( !memcmp( im.data + 30, utf_expect, sizeof( utf_expect ) ), ".utf8 exact UTF-8 bytes plus NUL" );
+ CHECK( !memcmp( im.data + 43, raw_expect, sizeof( raw_expect ) ), ".byte expressions" );
+ CHECK( __cpu_data_get_u16( im.data + 47 ) == 0x0410, ".integer first list element" );
+ CHECK( __cpu_data_get_u16( im.data + 49 ) == 0x043d, ".integer second list element" );
+ CHECK( __cpu_data_get_u16( im.data + 51 ) == 0, ".integer terminator" );
+ CHECK( im.data[53] == 65 && im.data[54] == 66 && im.data[55] == 0, ".int alias and list" );
+ for( i = 56; i < 64; i++ ) CHECK( im.data[i] == 0, ".align expression padding" );
+ CHECK( __cpu_data_get_u64( im.data + 64 ) == 11, "first 64-bit integer list element" );
+ CHECK( __cpu_data_get_u64( im.data + 72 ) == 42, "second 64-bit integer list element" );
+
+ CHECK( __cpu_program_set( im.code, im.code_size ) == 0, "program set" );
+ CHECK( __cpu_data_set( im.data, im.data_size ) == 0, "data set" );
+ rc = __cpu_run();
+ CHECK( rc == 0, "assembled expression program run" );
+ CHECK( __cpu_data_get_u64( __cpu_reg_ptr( 64, 0x03000 ) ) == 42, "symbolic register address via forward .equ" );
+ CHECK( __cpu_data_get_u64( __cpu_reg_ptr( 64, 0x03008 ) ) == 42, "DATA label+offset expression" );
+ cpu_asm_image_free( &im );
+
+ CHECK( cpu_assemble_text( bad_ucs, &im, err, sizeof( err ) ) != 0, "strict UCS-2 rejects non-BMP character" );
+ CHECK( strstr( err, "strict UCS-2" ) != 0, "strict UCS-2 diagnostic" );
+ CHECK( cpu_assemble_text( bad_byte, &im, err, sizeof( err ) ) != 0, ".byte rejects >8-bit value" );
+ CHECK( cpu_assemble_text( bad_cycle, &im, err, sizeof( err ) ) != 0, "cyclic .equ rejected" );
+
+ __cpu_free_context();
+ puts( "libcpu assembler directives/expressions regression: PASS" );
+ return( 0 );
+}