diff options
Diffstat (limited to 'tests/tst-control.c')
| -rw-r--r-- | tests/tst-control.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/tests/tst-control.c b/tests/tst-control.c new file mode 100644 index 0000000..7a3300f --- /dev/null +++ b/tests/tst-control.c @@ -0,0 +1,80 @@ +#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 alias_src[]= +".text\n" +" JZ end\n" +" JNZ end\n" +" JC end\n" +" JNC end\n" +" JO end\n" +" JNO end\n" +" JS end\n" +" JNS end\n" +"end:\n" +" HALT\n"; + +static const char src[]= +".text\n" +" JMP start\n" +"dead:\n" +" HALT\n" +"start:\n" +" LDI r64@0x00000, 3\n" +" LDI r64@0x00008, 1\n" +" CLR r64@0x00010\n" +"loop:\n" +" ISUB r64@0x00000, r64@0x00000, r64@0x00008\n" +" ICMP r64@0x00000, r64@0x00010\n" +" JNZ loop\n" +" JSET ZF, done\n" +" LDI r64@0x00018, 77\n" +"done:\n" +" LDI r64@0x00018, 42\n" +" HALT\n"; + +int +main( void ) +{ + cpu_asm_image im, aliases; + cpu_instruction insn; + mpu_int64_t zero, forty_two; + char err[256]; + int rc; + + __cpu_init(); + CHECK( cpu_assemble_text( alias_src, &aliases, err, sizeof( err ) ) == 0, err ); + CHECK( aliases.code_size == 90, "all eight jump aliases assembled" ); + cpu_asm_image_free( &aliases ); + + CHECK( cpu_assemble_text( src, &im, err, sizeof( err ) ) == 0, err ); + CHECK( im.code_size > 0, "control-flow code produced" ); + CHECK( __cpu_program_set( im.code, im.code_size ) == 0, "program set" ); + + __cpu_pc = 0; + CHECK( __cpu_decode( &insn ) == 0, "decode JMP" ); + CHECK( insn.opcode == CPU_OP_JMP, "first opcode JMP" ); + CHECK( insn.length == 10, "JMP length" ); + CHECK( insn.operand[0].type == CPU_OPERAND_CODE64, "JMP CODE64 operand" ); + CHECK( insn.operand[0].value.code64 < im.code_size, "JMP target in PROGRAM" ); + + rc = __cpu_run(); + CHECK( rc == CPU_EXEC_SUCCESS, "control-flow run" ); + CHECK( __cpu_pc == im.code_size, "PC after final HALT" ); + CHECK( __cpu_gth() != 0, "HALT flag set" ); + + iatoi( ( mpu_int * ) zero, "0", NB_I64 ); + iatoi( ( mpu_int * ) forty_two, "42", NB_I64 ); + CHECK( !memcmp( __cpu_reg_ptr( 64, 0 ), zero, NB_I64 ), "backward JNZ loop reached zero" ); + CHECK( !memcmp( __cpu_reg_ptr( 64, 24 ), forty_two, NB_I64 ), "forward JSET reached done label" ); + + cpu_asm_image_free( &im ); + __cpu_free_context(); + puts( "libcpu control-flow regression: PASS" ); + return( 0 ); +} |
