> compile NEMU

ysyx_22040000 李心杨
Linux calcite 6.1.69 #1-NixOS SMP PREEMPT_DYNAMIC Wed Dec 20 16:00:29 UTC 2023 x86_64 GNU/Linux
 10:08:10  up 1 day 10:24,  2 users,  load average: 0.92, 0.71, 0.58
This commit is contained in:
tracer-ysyx 2024-01-13 10:08:10 +08:00 committed by xinyangli
parent d20ea706e8
commit bbdc49b229

View file

@ -1,27 +1,26 @@
#include "sys/types.h" #include "sys/types.h"
#include "unistd.h" #include "unistd.h"
#include <check.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <addrexp.h> #include <addrexp.h>
#include <addrexp_lex.h> #include <addrexp_lex.h>
#include <assert.h> #include <assert.h>
#include <check.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> #include <time.h>
char buf[65536] = {}, ref_buf[65536] = {}; char buf[65536] = {}, ref_buf[65536] = {};
static char code_buf[65536 + 128] = {}; // a little larger than `buf` static char code_buf[65536 + 128] = {}; // a little larger than `buf`
const int buf_start_pos = 0; const int buf_start_pos = 0;
char *buf_ptr = buf + buf_start_pos, *ref_buf_ptr = ref_buf; char *buf_ptr = buf + buf_start_pos, *ref_buf_ptr = ref_buf;
static char *code_format = static char *code_format = "#include <stdio.h>\n"
"#include <stdio.h>\n" "#include <stdint.h>\n"
"#include <stdint.h>\n" "int main() { "
"int main() { " " uint32_t result = %s; "
" uint32_t result = %s; " " printf(\"%%u\", result); "
" printf(\"%%u\", result); " " return 0; "
" return 0; " "}";
"}";
void gen(char c) { void gen(char c) {
*(buf_ptr++) = c; *(buf_ptr++) = c;
@ -31,31 +30,40 @@ void gen(char c) {
void gen_num(void) { void gen_num(void) {
uint32_t num = rand(); uint32_t num = rand();
int len = 0, ref_len = 0; int len = 0, ref_len = 0;
switch(rand() % 3) { switch (rand() % 3) {
case 0: case 0:
len = snprintf(buf_ptr, 100, "%u", num); len = snprintf(buf_ptr, 100, "%u", num);
ref_len = snprintf(ref_buf_ptr, 100, "%uU", num); ref_len = snprintf(ref_buf_ptr, 100, "%uU", num);
break; break;
case 1: case 1:
len = snprintf(buf_ptr, 100, "0x%x", num); len = snprintf(buf_ptr, 100, "0x%x", num);
ref_len = snprintf(ref_buf_ptr, 100, "%uU", num); ref_len = snprintf(ref_buf_ptr, 100, "%uU", num);
break; break;
case 2: case 2:
len = snprintf(buf_ptr, 100, "%d", num); len = snprintf(buf_ptr, 100, "%d", num);
ref_len = snprintf(ref_buf_ptr, 100, "%d", num); ref_len = snprintf(ref_buf_ptr, 100, "%d", num);
break; break;
default: assert(0); default:
assert(0);
} }
buf_ptr += len; buf_ptr += len;
ref_buf_ptr += ref_len; ref_buf_ptr += ref_len;
} }
void gen_rand_op(void) { void gen_rand_op(void) {
switch(rand() % 4) { switch (rand() % 4) {
case 0: gen('+'); break; case 0:
case 1: gen('-'); break; gen('+');
case 2: gen('*'); break; break;
case 3: gen('/'); break; case 1:
gen('-');
break;
case 2:
gen('*');
break;
case 3:
gen('/');
break;
} }
} }
@ -63,11 +71,23 @@ void gen_rand_expr(void) {
int choice = rand() % 3; int choice = rand() % 3;
if (buf_ptr - buf > 2000) { if (buf_ptr - buf > 2000) {
choice = 0; choice = 0;
} }
switch (choice) { switch (choice) {
case 0: gen_num(); break; case 0:
case 1: gen('('); gen_rand_expr(); gen(')'); break; gen_num();
default: gen_rand_expr(); gen(' '); gen_rand_op(); gen(' '); gen_rand_expr(); break; break;
case 1:
gen('(');
gen_rand_expr();
gen(')');
break;
default:
gen_rand_expr();
gen(' ');
gen_rand_op();
gen(' ');
gen_rand_expr();
break;
} }
} }
@ -82,8 +102,9 @@ START_TEST(test_expr_random_100) {
fputs(code_buf, fp); fputs(code_buf, fp);
fclose(fp); fclose(fp);
int ret = system("gcc /tmp/.code.c -Werror=div-by-zero -o /tmp/.expr 2>/dev/null"); int ret =
if(ret == 256) { system("gcc /tmp/.code.c -Werror=div-by-zero -o /tmp/.expr 2>/dev/null");
if (ret == 256) {
// Probably devide by zero. Skip // Probably devide by zero. Skip
goto clean_up; goto clean_up;
} }
@ -96,53 +117,73 @@ START_TEST(test_expr_random_100) {
ret = fscanf(fp, "%u", &reference); ret = fscanf(fp, "%u", &reference);
ck_assert(ret == 1); ck_assert(ret == 1);
pclose(fp); pclose(fp);
// fprintf(stderr, "\n\tbuf = %s\n\taddr = %u, reference = %u", buf, addr, reference); // fprintf(stderr, "\n\tbuf = %s\n\taddr = %u, reference = %u", buf, addr,
// reference);
yy_scan_string(buf + buf_start_pos); yy_scan_string(buf + buf_start_pos);
uint32_t addr; uint32_t addr;
ck_assert(!yyparse(&addr)); ck_assert(!yyparse(&addr));
yylex_destroy(); yylex_destroy();
ck_assert_msg(addr == reference, "\n\tbuf = %s\n\taddr = %u, reference = %u\n", buf, addr, reference); ck_assert_msg(addr == reference,
"\n\tbuf = %s\n\t(addr = %u) != (reference = %u)\n", buf, addr,
reference);
clean_up: clean_up:
while(buf_ptr != buf + buf_start_pos) { while (buf_ptr != buf + buf_start_pos) {
*(--buf_ptr) = '\0'; *(--buf_ptr) = '\0';
} }
while(ref_buf_ptr != ref_buf) { while (ref_buf_ptr != ref_buf) {
*(--ref_buf_ptr) = '\0'; *(--ref_buf_ptr) = '\0';
} }
} END_TEST }
END_TEST
START_TEST(test_test2) { struct {
; const char *expr;
} END_TEST uint32_t reference;
} exprs[] = {
{"-1", 0xFFFFFFFFU},
{"--1", 0x1},
};
START_TEST(test_expr_negative_operand) {
yy_scan_string(exprs[_i].expr);
uint32_t addr;
ck_assert(!yyparse(&addr));
yylex_destroy();
ck_assert_msg(addr == exprs[_i].reference,
"\n\texpr = %s\n\t(addr = %u) != (reference = %u)\n", exprs[_i].expr,
addr, exprs[_i].reference);
}
END_TEST
Suite *expr_suite(void) { Suite *expr_suite(void) {
Suite *s; Suite *s;
TCase *tc_core; TCase *tc_core;
s = suite_create("Expr test"); s = suite_create("Expr test");
tc_core = tcase_create("Core"); tc_core = tcase_create("Core");
tcase_add_loop_test(tc_core, test_expr_random_100, 0, 100); tcase_add_loop_test(tc_core, test_expr_random_100, 0, 100);
tcase_add_test(tc_core, test_test2); tcase_add_loop_test(tc_core, test_expr_negative_operand, 0,
suite_add_tcase(s, tc_core); sizeof(exprs) / sizeof(exprs[0]));
suite_add_tcase(s, tc_core);
return s; return s;
} }
int main(void) { int main(void) {
int number_failed; int number_failed;
Suite *s; Suite *s;
SRunner *sr; SRunner *sr;
s = expr_suite(); s = expr_suite();
sr = srunner_create(s); sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL); srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr); number_failed = srunner_ntests_failed(sr);
srunner_free(sr); srunner_free(sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
} }