diff --git a/cpu-tests/.gitignore b/cpu-tests/.gitignore new file mode 100644 index 0000000..9c45e66 --- /dev/null +++ b/cpu-tests/.gitignore @@ -0,0 +1 @@ +/Makefile.* diff --git a/cpu-tests/Makefile b/cpu-tests/Makefile new file mode 100644 index 0000000..6d8f6eb --- /dev/null +++ b/cpu-tests/Makefile @@ -0,0 +1,22 @@ +.PHONY: all run clean latest $(ALL) + +ALL = $(basename $(notdir $(shell find tests/. -name "*.c"))) + +all: $(addprefix Makefile., $(ALL)) + @echo "" $(ALL) + +$(ALL): %: Makefile.% + +Makefile.%: tests/%.c latest + @/bin/echo -e "NAME = $*\nSRCS = $<\nLIBS += klib\ninclude $${AM_HOME}/Makefile" > $@ + -@make -s -f $@ ARCH=$(ARCH) $(MAKECMDGOALS) + -@rm -f Makefile.$* + +# cancel rules included by $(AM_HOME)/Makefile.check +image: ; +default $(MAKECMDGOALS): all ; + +clean: + rm -rf Makefile.* build/ + +latest: diff --git a/cpu-tests/include/trap.h b/cpu-tests/include/trap.h new file mode 100644 index 0000000..ed23ab7 --- /dev/null +++ b/cpu-tests/include/trap.h @@ -0,0 +1,13 @@ +#ifndef __TRAP_H__ +#define __TRAP_H__ + +#include +#include +#include + +__attribute__((noinline)) +void nemu_assert(bool cond) { + if (!cond) halt(1); +} + +#endif diff --git a/cpu-tests/tests/add-longlong.c b/cpu-tests/tests/add-longlong.c new file mode 100644 index 0000000..e3d354a --- /dev/null +++ b/cpu-tests/tests/add-longlong.c @@ -0,0 +1,22 @@ +#include "trap.h" + +long long add(long long a, long long b) { + long long c = a + b; + return c; +} + +long long test_data[] = {0, 1, 2, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0x8000000000000001LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL}; +long long ans[] = {0LL, 0x1LL, 0x2LL, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0x8000000000000001LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL, 0x1LL, 0x2LL, 0x3LL, 0x8000000000000000LL, 0x8000000000000001LL, 0x8000000000000002LL, 0xffffffffffffffffLL, 0LL, 0x2LL, 0x3LL, 0x4LL, 0x8000000000000001LL, 0x8000000000000002LL, 0x8000000000000003LL, 0LL, 0x1LL, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0x8000000000000001LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL, 0LL, 0x7ffffffffffffffdLL, 0x7ffffffffffffffeLL, 0x8000000000000000LL, 0x8000000000000001LL, 0x8000000000000002LL, 0xffffffffffffffffLL, 0LL, 0x1LL, 0x7ffffffffffffffeLL, 0x7fffffffffffffffLL, 0x8000000000000001LL, 0x8000000000000002LL, 0x8000000000000003LL, 0LL, 0x1LL, 0x2LL, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL, 0LL, 0x7ffffffffffffffdLL, 0x7ffffffffffffffeLL, 0x7fffffffffffffffLL, 0xfffffffffffffffcLL, 0xfffffffffffffffdLL, 0xffffffffffffffffLL, 0LL, 0x1LL, 0x7ffffffffffffffeLL, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0xfffffffffffffffdLL, 0xfffffffffffffffeLL}; + +#define NR_DATA LENGTH(test_data) + +int main() { + int i, j, ans_idx = 0; + for(i = 0; i < NR_DATA; i ++) { + for(j = 0; j < NR_DATA; j ++) { + nemu_assert(add(test_data[i], test_data[j]) == ans[ans_idx ++]); + } + } + + return 0; +} diff --git a/cpu-tests/tests/add.c b/cpu-tests/tests/add.c new file mode 100644 index 0000000..b44af56 --- /dev/null +++ b/cpu-tests/tests/add.c @@ -0,0 +1,25 @@ +#include "trap.h" + +int add(int a, int b) { + int c = a + b; + return c; +} + +int test_data[] = {0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff}; +int ans[] = {0, 0x1, 0x2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, 0x1, 0x2, 0x3, 0x80000000, 0x80000001, 0x80000002, 0xffffffff, 0, 0x2, 0x3, 0x4, 0x80000001, 0x80000002, 0x80000003, 0, 0x1, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, 0, 0x7ffffffd, 0x7ffffffe, 0x80000000, 0x80000001, 0x80000002, 0xffffffff, 0, 0x1, 0x7ffffffe, 0x7fffffff, 0x80000001, 0x80000002, 0x80000003, 0, 0x1, 0x2, 0x7fffffff, 0x80000000, 0xfffffffe, 0xffffffff, 0, 0x7ffffffd, 0x7ffffffe, 0x7fffffff, 0xfffffffc, 0xfffffffd, 0xffffffff, 0, 0x1, 0x7ffffffe, 0x7fffffff, 0x80000000, 0xfffffffd, 0xfffffffe}; + +#define NR_DATA LENGTH(test_data) + +int main() { + int i, j, ans_idx = 0; + for(i = 0; i < NR_DATA; i ++) { + for(j = 0; j < NR_DATA; j ++) { + nemu_assert(add(test_data[i], test_data[j]) == ans[ans_idx ++]); + } + nemu_assert(j == NR_DATA); + } + + nemu_assert(i == NR_DATA); + + return 0; +} diff --git a/cpu-tests/tests/bit.c b/cpu-tests/tests/bit.c new file mode 100644 index 0000000..bfa5f94 --- /dev/null +++ b/cpu-tests/tests/bit.c @@ -0,0 +1,46 @@ +#include "trap.h" + +typedef unsigned char uint8_t; +__attribute__((noinline)) +bool getbit(void *buf, int offset){ + int byte = offset >> 3; + offset &= 7; + uint8_t mask = 1 << offset; + return (((uint8_t *)buf)[byte] & mask) != 0; +} +__attribute__((noinline)) +void setbit(void *buf, int offset, bool bit){ + int byte = offset >> 3; + offset &= 7; + uint8_t mask = 1 << offset; + + uint8_t * volatile p = buf + byte; + *p = (bit == 0 ? (*p & ~mask) : (*p | mask)); +} + +int main() { + uint8_t buf[2]; + + buf[0] = 0xaa; + buf[1] = 0x0; + nemu_assert(getbit(buf, 0) == 0); + nemu_assert(getbit(buf, 1) == 1); + nemu_assert(getbit(buf, 2) == 0); + nemu_assert(getbit(buf, 3) == 1); + nemu_assert(getbit(buf, 4) == 0); + nemu_assert(getbit(buf, 5) == 1); + nemu_assert(getbit(buf, 6) == 0); + nemu_assert(getbit(buf, 7) == 1); + + setbit(buf, 8, 1); + setbit(buf, 9, 0); + setbit(buf, 10, 1); + setbit(buf, 11, 0); + setbit(buf, 12, 1); + setbit(buf, 13, 0); + setbit(buf, 14, 1); + setbit(buf, 15, 0); + nemu_assert(buf[1] == 0x55); + + return 0; +} diff --git a/cpu-tests/tests/bubble-sort.c b/cpu-tests/tests/bubble-sort.c new file mode 100644 index 0000000..2cf712e --- /dev/null +++ b/cpu-tests/tests/bubble-sort.c @@ -0,0 +1,39 @@ +#include "trap.h" + +#define N 20 + +int a[N] = {2, 12, 14, 6, 13, 15, 16, 10, 0, 18, 11, 19, 9, 1, 7, 5, 4, 3, 8, 17}; + +void bubble_sort() { + int i, j, t; + for(j = 0; j < N; j ++) { + for(i = 0; i < N - 1 - j; i ++) { + if(a[i] > a[i + 1]) { + t = a[i]; + a[i] = a[i + 1]; + a[i + 1] = t; + } + } + } +} + +int main() { + bubble_sort(); + + int i; + for(i = 0; i < N; i ++) { + nemu_assert(a[i] == i); + } + + nemu_assert(i == N); + + bubble_sort(); + + for(i = 0; i < N; i ++) { + nemu_assert(a[i] == i); + } + + nemu_assert(i == N); + + return 0; +} diff --git a/cpu-tests/tests/div.c b/cpu-tests/tests/div.c new file mode 100644 index 0000000..cf05b9c --- /dev/null +++ b/cpu-tests/tests/div.c @@ -0,0 +1,21 @@ +#include "trap.h" + +#define N 10 +int a[N]; + +int main() { + int i, j; + for(i = 0; i < N; i ++) + a[i] = i; + for(i = 0; i < N; i ++) + for(j = 1; j < N + 1; j ++) + a[i] *= j; + for(i = 0; i < N; i ++) + for(j = 1; j < N + 1; j ++) + a[i] /= j; + + for(i = 0; i < N; i ++) + nemu_assert(a[i] == i); + + return 0; +} diff --git a/cpu-tests/tests/dummy.c b/cpu-tests/tests/dummy.c new file mode 100644 index 0000000..4cce7f6 --- /dev/null +++ b/cpu-tests/tests/dummy.c @@ -0,0 +1,3 @@ +int main() { + return 0; +} diff --git a/cpu-tests/tests/fact.c b/cpu-tests/tests/fact.c new file mode 100644 index 0000000..2ea6c1e --- /dev/null +++ b/cpu-tests/tests/fact.c @@ -0,0 +1,20 @@ +#include "trap.h" + +int f[15]; +int ans[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600}; + +int fact(int n) { + if(n == 0 || n == 1) return 1; + else return fact(n - 1) * n; +} + +int main() { + int i; + for(i = 0; i < 13; i ++) { + f[i] = fact(i); + nemu_assert(f[i] == ans[i]); + } + + return 0; +} + diff --git a/cpu-tests/tests/fib.c b/cpu-tests/tests/fib.c new file mode 100644 index 0000000..4670b8a --- /dev/null +++ b/cpu-tests/tests/fib.c @@ -0,0 +1,16 @@ +#include "trap.h" + +int fib[40] = {1, 1}; +int ans[] = {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155}; + +int main() { + int i; + for(i = 2; i < 40; i ++) { + fib[i] = fib[i - 1] + fib[i - 2]; + nemu_assert(fib[i] == ans[i]); + } + + nemu_assert(i == 40); + + return 0; +} diff --git a/cpu-tests/tests/goldbach.c b/cpu-tests/tests/goldbach.c new file mode 100644 index 0000000..ee2ae5f --- /dev/null +++ b/cpu-tests/tests/goldbach.c @@ -0,0 +1,34 @@ +#include "trap.h" + +int is_prime(int n) { + if(n < 2) return 0; + + int i; + for(i = 2; i < n; i ++) { + if(n % i == 0) { + return 0; + } + } + + return 1; +} + +int goldbach(int n) { + int i; + for(i = 2; i < n; i ++) { + if(is_prime(i) && is_prime(n - i)) { + return 1; + } + } + + return 0; +} + +int main() { + int n; + for(n = 4; n <= 30; n += 2) { + nemu_assert(goldbach(n) == 1); + } + + return 0; +} diff --git a/cpu-tests/tests/hello-str.c b/cpu-tests/tests/hello-str.c new file mode 100644 index 0000000..bf80972 --- /dev/null +++ b/cpu-tests/tests/hello-str.c @@ -0,0 +1,16 @@ +#include "trap.h" + +char buf[128]; + +int main() { + sprintf(buf, "%s", "Hello world!\n"); + nemu_assert(strcmp(buf, "Hello world!\n") == 0); + + sprintf(buf, "%d + %d = %d\n", 1, 1, 2); + nemu_assert(strcmp(buf, "1 + 1 = 2\n") == 0); + + sprintf(buf, "%d + %d = %d\n", 2, 10, 12); + nemu_assert(strcmp(buf, "2 + 10 = 12\n") == 0); + + return 0; +} diff --git a/cpu-tests/tests/if-else.c b/cpu-tests/tests/if-else.c new file mode 100644 index 0000000..3733034 --- /dev/null +++ b/cpu-tests/tests/if-else.c @@ -0,0 +1,28 @@ +#include "trap.h" + +int if_else(int n) { + int cost; + if(n > 500) cost = 150; + else if(n > 300) cost = 100; + else if(n > 100) cost = 75; + else if(n > 50) cost = 50; + else cost = 0; + + return cost; +} + +int test_data[] = {-1, 0, 49, 50, 51, 99, 100, 101, 299, 300, 301, 499, 500, 501}; +int ans[] = {0, 0, 0, 0, 50, 50, 50, 75, 75, 75, 100, 100, 100, 150}; + +#define NR_DATA LENGTH(test_data) + +int main() { + int i, ans_idx = 0; + for(i = 0; i < NR_DATA; i ++) { + nemu_assert(if_else(test_data[i]) == ans[ans_idx ++]); + } + + nemu_assert(i == NR_DATA); + + return 0; +} diff --git a/cpu-tests/tests/leap-year.c b/cpu-tests/tests/leap-year.c new file mode 100644 index 0000000..dfcffd6 --- /dev/null +++ b/cpu-tests/tests/leap-year.c @@ -0,0 +1,16 @@ +#include "trap.h" + +int is_leap_year(int n) { + return (n % 4 == 0 && n % 100 != 0) || (n % 400 == 0); +} + +int ans[] = {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}; + +int main() { + int i; + for(i = 0; i < 125; i ++) { + nemu_assert(is_leap_year(i + 1890) == ans[i]); + } + + return 0; +} diff --git a/cpu-tests/tests/load-store.c b/cpu-tests/tests/load-store.c new file mode 100644 index 0000000..1a8f9c1 --- /dev/null +++ b/cpu-tests/tests/load-store.c @@ -0,0 +1,45 @@ +#include "trap.h" + +unsigned short mem[] = { + 0x0, 0x0258, 0x4abc, 0x7fff, 0x8000, 0x8100, 0xabcd, 0xffff +}; + +unsigned lh_ans[] = { + 0x00000000, 0x00000258, 0x00004abc, 0x00007fff, 0xffff8000, 0xffff8100, 0xffffabcd, 0xffffffff +}; + +unsigned lhu_ans[] = { + 0x00000000, 0x00000258, 0x00004abc, 0x00007fff, 0x00008000, 0x00008100, 0x0000abcd, 0x0000ffff +}; + +unsigned sh_ans[] = { + 0x0000fffd, 0x0000fff7, 0x0000ffdf, 0x0000ff7f, 0x0000fdff, 0x0000f7ff, 0x0000dfff, 0x00007fff +}; + +unsigned lwlr_ans[] = { + 0xbc025800, 0x7fff4a, 0xcd810080, 0xffffab +}; + +int main() { + unsigned i; + + for(i = 0; i < LENGTH(mem); i ++) { + nemu_assert((short)mem[i] == lh_ans[i]); + } + + for(i = 0; i < LENGTH(mem); i ++) { + nemu_assert(mem[i] == lhu_ans[i]); + } + + for(i = 0; i < ((LENGTH(mem) / 2) - 1); i ++) { + unsigned x = ((unsigned*)((void*)mem + 1))[i]; + nemu_assert(x == lwlr_ans[i]); + } + + for(i = 0; i < LENGTH(mem); i ++) { + mem[i] = ~(1 << (2 * i + 1)); + nemu_assert(mem[i] == sh_ans[i]); + } + + return 0; +} diff --git a/cpu-tests/tests/matrix-mul.c b/cpu-tests/tests/matrix-mul.c new file mode 100644 index 0000000..6ae34bd --- /dev/null +++ b/cpu-tests/tests/matrix-mul.c @@ -0,0 +1,60 @@ +#include "trap.h" + +#define N 10 +int a[N][N] = { +{31, -73, -67, -28, 87, -17, -15, -35, -53, -54}, +{52, 36, 9, -91, -27, -78, 42, 82, 19, -6}, +{41, -56, 31, 32, -52, 74, 28, 20, 55, -72}, +{-59, 2, -79, -8, 44, 55, -83, -95, -45, 50}, +{-95, 61, -63, 62, -16, 52, 40, 92, -32, -26}, +{-99, 52, 96, 63, -75, -74, -82, 82, -95, 42}, +{11, -22, 27, -27, -27, -76, -71, 58, -40, -65}, +{91, -53, -67, 72, 36, -77, -3, 93, -24, 97}, +{-52, -11, -77, -93, -92, -24, 70, 18, 56, 88}, +{-43, -41, -26, 11, -84, -14, -41, 83, 27, -11} +}; +int b[N][N] = { + {-48, -70, -40, -82, -74, -63, -59, -72, -100, -72}, +{5, -84, 28, 56, 60, -33, -42, -50, -83, -83}, +{-5, 5, 48, 75, -78, -9, 9, 2, 88, 70}, +{69, 23, 66, 66, -11, 50, 67, 18, -58, 76}, +{30, 45, 32, 25, -73, 57, -67, -14, 53, -33}, +{98, -86, -63, 80, -45, -88, 80, -64, 58, -84}, +{-55, -39, -13, -27, -37, 8, -96, 84, -89, 31}, +{-82, 58, 81, -41, -58, 36, 76, -79, -29, 23}, +{86, -46, 16, -18, 81, 90, 35, -90, 43, 55}, +{-38, -19, -40, 82, -76, 57, -29, -2, 79, -48}, +}; + +int ans[N][N] = { + {-1317, 10379, -5821, -14322, -4330, -3114, -9940, 7033, -1883, -6027}, + {-24266, -861, 4044, -19824, -223, 886, -11988, -6442, -13846, -1054}, + {9783, -7073, -918, -5911, -967, -7100, 14605, -7556, -3439, 9607}, + {15980, -520, -13297, 15043, 6185, -3654, 1325, 4193, 16925, -17761}, + {2566, 3187, 10248, 7925, 6318, 1421, 14648, 700, -12193, 1083}, + {-12603, 19006, 20952, 18599, -1539, 5184, 17408, 6740, 6264, 15114}, + {-12715, 15121, 9963, -13717, 2411, -2196, 6147, -1698, -3389, 8200}, + {-19007, 12417, 5723, -11309, -19242, 15740, -3791, -3949, -13130, -21}, + {-12557, -5970, -11570, -8905, 12227, 7814, -5094, 4532, 1071, -1309}, + {-2955, 9381, 6372, -6898, 9117, 5753, 20778, -5045, 1047, 12114}}; + +int c[N][N]; + +int main() { + int i, j, k; + for(i = 0; i < N; i ++) { + for(j = 0; j < N; j ++) { + c[i][j] = 0; + for(k = 0; k < N; k ++) { + c[i][j] += a[i][k] * b[k][j]; + } + nemu_assert(c[i][j] == ans[i][j]); + nemu_assert(k == N); + } + nemu_assert(j == N); + } + + nemu_assert(i == N); + + return 0; +} diff --git a/cpu-tests/tests/max.c b/cpu-tests/tests/max.c new file mode 100644 index 0000000..9649481 --- /dev/null +++ b/cpu-tests/tests/max.c @@ -0,0 +1,27 @@ +#include "trap.h" + +int max(int x, int y) { + int z; + if(x > y) { z = x; } + else { z = y; } + return z; +} + +int test_data[] = {0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff}; +int ans[] = {0, 0x1, 0x2, 0x7fffffff, 0, 0, 0, 0, 0x1, 0x1, 0x2, 0x7fffffff, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x7fffffff, 0x2, 0x2, 0x2, 0x2, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0, 0x1, 0x2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, 0, 0x1, 0x2, 0x7fffffff, 0x80000001, 0x80000001, 0xfffffffe, 0xffffffff, 0, 0x1, 0x2, 0x7fffffff, 0xfffffffe, 0xfffffffe, 0xfffffffe, 0xffffffff, 0, 0x1, 0x2, 0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; + +#define NR_DATA LENGTH(test_data) + +int main() { + int i, j, ans_idx = 0; + for(i = 0; i < NR_DATA; i ++) { + for(j = 0; j < NR_DATA; j ++) { + nemu_assert(max(test_data[i], test_data[j]) == ans[ans_idx ++]); + } + nemu_assert(j == NR_DATA); + } + + nemu_assert(i == NR_DATA); + + return 0; +} diff --git a/cpu-tests/tests/min3.c b/cpu-tests/tests/min3.c new file mode 100644 index 0000000..0c8b885 --- /dev/null +++ b/cpu-tests/tests/min3.c @@ -0,0 +1,31 @@ +#include "trap.h" + +int min3(int x, int y, int z) { + int m; + if(x < y) { m = x; } + else { m = y; } + if(z < m) m = z; + return m; +} + +int test_data[] = {0, 0x7fffffff, 0x80000000, 0xffffffff}; +int ans [] = {0, 0, -2147483648, -1, 0, 0, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1, 0, 0, -2147483648, -1, 0, 2147483647, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1, -1, -1, -2147483648, -1, -2147483648, -2147483648, -2147483648, -2147483648, -1, -1, -2147483648, -1}; + +#define NR_DATA LENGTH(test_data) + +int main() { + int i, j, k, ans_idx = 0; + for(i = 0; i < NR_DATA; i ++) { + for(j = 0; j < NR_DATA; j ++) { + for(k = 0; k < NR_DATA; k ++) { + nemu_assert(min3(test_data[i], test_data[j], test_data[k]) == ans[ans_idx ++]); + } + nemu_assert(k == NR_DATA); + } + nemu_assert(j == NR_DATA); + } + + nemu_assert(i == NR_DATA); + + return 0; +} diff --git a/cpu-tests/tests/mov-c.c b/cpu-tests/tests/mov-c.c new file mode 100644 index 0000000..9b984b0 --- /dev/null +++ b/cpu-tests/tests/mov-c.c @@ -0,0 +1,25 @@ +#include "trap.h" + +volatile int A[10]; +volatile int b; + +int main() { + A[0] = 0; + A[1] = 1; + A[2] = 2; + A[3] = 3; + A[4] = 4; + + b = A[3]; + A[5] = b; + + nemu_assert(A[0] == 0); + nemu_assert(A[1] == 1); + nemu_assert(A[2] == 2); + nemu_assert(A[3] == 3); + nemu_assert(A[4] == 4); + nemu_assert(b == 3); + nemu_assert(A[5] == 3); + + return 0; +} diff --git a/cpu-tests/tests/movsx.c b/cpu-tests/tests/movsx.c new file mode 100644 index 0000000..93fd142 --- /dev/null +++ b/cpu-tests/tests/movsx.c @@ -0,0 +1,33 @@ +#include "trap.h" + +volatile int A[10]; +volatile int b; +volatile signed char C[10]; +int main() { + A[0] = 0; + A[1] = 1; + A[2] = 2; + A[3] = 3; + A[4] = 4; + + b = A[3]; + A[5] = b; + C[0] = 'a'; + nemu_assert(C[0] == 'a'); + C[1] = C[0]; + nemu_assert(C[1] == 'a'); + A[0] = (int)C[0]; + nemu_assert(A[0] == 'a'); + C[1] = 0x80; + A[0] = (int)C[1]; + nemu_assert(A[1] == 1); + nemu_assert(A[2] == 2); + nemu_assert(A[3] == 3); + nemu_assert(A[4] == 4); + nemu_assert(b == 3); + nemu_assert(A[5] == 3); + nemu_assert(C[1] == 0xffffff80); + nemu_assert(A[0] == 0xffffff80); + + return 0; +} diff --git a/cpu-tests/tests/mul-longlong.c b/cpu-tests/tests/mul-longlong.c new file mode 100644 index 0000000..a65ba04 --- /dev/null +++ b/cpu-tests/tests/mul-longlong.c @@ -0,0 +1,26 @@ +#include "trap.h" + +long long mul(long long a,long long b) { + long long ans = a*b; + return ans; +} + +int test_data[] = { 0xaeb1c2aa, 0x4500ff2b, 0x877190af, 0x11f42438}; +long long ans[] = { 0x19d29ab9db1a18e4LL, 0xea15986d3ac3088eLL, 0x2649e980fc0db236LL, 0xfa4c43da0a4a7d30LL, 0x1299898e2c56b139LL, 0xdf8123d50a319e65LL, 0x4d6dfa84c15dd68LL, 0x38c5d79b9e4357a1LL, 0xf78b91cb1efc4248LL, 0x14255a47fdfcc40LL}; + +#define NR_DATA LENGTH(test_data) + +int main() { + int i,j,ans_idx = 0; + for (i = 0;i < NR_DATA;i++) { + for (j = i;j < NR_DATA;j++) { + nemu_assert(ans[ans_idx++] == mul(test_data[i],test_data[j])); + } + nemu_assert(j == NR_DATA); + } + + nemu_assert(i == NR_DATA); + + return 0; +} + diff --git a/cpu-tests/tests/pascal.c b/cpu-tests/tests/pascal.c new file mode 100644 index 0000000..cbc8420 --- /dev/null +++ b/cpu-tests/tests/pascal.c @@ -0,0 +1,30 @@ +#include "trap.h" + +#define N 31 + +int a[N]; +int ans[] = {1, 30, 435, 4060, 27405, 142506, 593775, 2035800, 5852925, 14307150, 30045015, 54627300, 86493225, 119759850, 145422675, 155117520, 145422675, 119759850, 86493225, 54627300, 30045015, 14307150, 5852925, 2035800, 593775, 142506, 27405, 4060, 435, 30, 1}; + +int main() { + int i, j; + int t0, t1; + a[0] = a[1] = 1; + + for(i = 2; i < N; i ++) { + t0 = 1; + for(j = 1; j < i; j ++) { + t1 = a[j]; + a[j] = t0 + t1; + t0 = t1; + } + a[i] = 1; + } + + for(j = 0; j < N; j ++) { + nemu_assert(a[j] == ans[j]); + } + + nemu_assert(j == N); + + return 0; +} diff --git a/cpu-tests/tests/prime.c b/cpu-tests/tests/prime.c new file mode 100644 index 0000000..7b9d022 --- /dev/null +++ b/cpu-tests/tests/prime.c @@ -0,0 +1,25 @@ +#include "trap.h" + +int ans[] = {101, 103, 107, 109, 113, 127, 131, 137, 139, 149}; + +int main() { + int m, i, n = 0; + int prime; + for(m = 101; m <= 150; m += 2) { + prime = 1; + for(i = 2; i < m; i ++) { + if(m % i == 0) { + prime = 0; + break; + } + } + if(prime) { + nemu_assert(i == ans[n]); + n ++; + } + } + + nemu_assert(n == 10); + + return 0; +} diff --git a/cpu-tests/tests/quick-sort.c b/cpu-tests/tests/quick-sort.c new file mode 100644 index 0000000..d528b7c --- /dev/null +++ b/cpu-tests/tests/quick-sort.c @@ -0,0 +1,49 @@ +#include "trap.h" + +#define N 20 + +int a[N] = {2, 12, 14, 6, 13, 15, 16, 10, 0, 18, 11, 19, 9, 1, 7, 5, 4, 3, 8, 17}; + +int partition(int *a, int p, int q) { + int pivot = a[p]; + int i = p, j = q; + while(i < j) { + while(i < j && a[j] > pivot) j --; + a[i] = a[j]; + + while(i < j && a[i] <= pivot) i ++; + a[j] = a[i]; + } + + a[i] = pivot; + return i; +} + +void quick_sort(int *a, int p, int q) { + if(p >= q) return; + + int m = partition(a, p, q); + quick_sort(a, p, m - 1); + quick_sort(a, m + 1, q); +} + +int main() { + quick_sort(a, 0, N - 1); + + int i; + for(i = 0; i < N; i ++) { + nemu_assert(a[i] == i); + } + + nemu_assert(i == N); + + quick_sort(a, 0, N - 1); + + for(i = 0; i < N; i ++) { + nemu_assert(a[i] == i); + } + + nemu_assert(i == N); + + return 0; +} diff --git a/cpu-tests/tests/recursion.c b/cpu-tests/tests/recursion.c new file mode 100644 index 0000000..39a5c89 --- /dev/null +++ b/cpu-tests/tests/recursion.c @@ -0,0 +1,46 @@ +#include "trap.h" + +int f0(int, int); +int f1(int, int); +int f2(int, int); +int f3(int, int); + +int (*func[])(int, int) = { + f0, f1, f2, f3, +}; + +int rec = 0, lvl = 0; + +int f0(int n, int l) { + if (l > lvl) lvl = l; + rec ++; + return n <= 0 ? 1 : func[3](n / 3, l + 1); +}; + +int f1(int n, int l) { + if (l > lvl) lvl = l; + rec ++; + return n <= 0 ? 1 : func[0](n - 1, l + 1); +}; + +int f2(int n, int l) { + if (l > lvl) lvl = l; + rec ++; + return n <= 0 ? 1 : func[1](n, l + 1) + 9; +}; + +int f3(int n, int l) { + if (l > lvl) lvl = l; + rec ++; + return n <= 0 ? 1 : func[2](n / 2, l + 1) * 3 + func[2](n / 2, l + 1) * 2; +}; + +int ans[] = {38270, 218, 20}; + +int main() { + int x = func[0](14371, 0); + nemu_assert(x == ans[0]); // answer + nemu_assert(rec == ans[1]); // # recursions + nemu_assert(lvl == ans[2]); // max depth + return 0; +} diff --git a/cpu-tests/tests/select-sort.c b/cpu-tests/tests/select-sort.c new file mode 100644 index 0000000..72b1a27 --- /dev/null +++ b/cpu-tests/tests/select-sort.c @@ -0,0 +1,42 @@ +#include "trap.h" + +#define N 20 + +int a[N] = {2, 12, 14, 6, 13, 15, 16, 10, 0, 18, 11, 19, 9, 1, 7, 5, 4, 3, 8, 17}; + +void select_sort() { + int i, j, k, t; + for(i = 0; i < N - 1; i ++) { + k = i; + for(j = i + 1; j < N; j ++) { + if(a[j] < a[k]) { + k = j; + } + } + + t = a[i]; + a[i] = a[k]; + a[k] = t; + } +} + +int main() { + select_sort(); + + int i; + for(i = 0; i < N; i ++) { + nemu_assert(a[i] == i); + } + + nemu_assert(i == N); + + select_sort(); + + for(i = 0; i < N; i ++) { + nemu_assert(a[i] == i); + } + + nemu_assert(i == N); + + return 0; +} diff --git a/cpu-tests/tests/shift.c b/cpu-tests/tests/shift.c new file mode 100644 index 0000000..c180aec --- /dev/null +++ b/cpu-tests/tests/shift.c @@ -0,0 +1,36 @@ +#include "trap.h" + +unsigned test[] = { + 0x12345678, 0x98765432, 0x0, 0xeffa1000, 0x7fffffff, 0x80000000, 0x33, 0xffffffff +}; + +unsigned srl_ans[] = { + 0x2468ac, 0x130eca8, 0x0, 0x1dff420, 0xffffff, 0x1000000, 0x0, 0x1ffffff +}; + +unsigned srlv_ans[] = { + 0x1234567, 0x4c3b2a1, 0x0, 0x1dff420, 0x7fffff, 0x400000, 0x0, 0x1fffff +}; + +unsigned srav_ans[] = { + 0x1234567, 0xfcc3b2a1, 0x0, 0xffdff420, 0x7fffff, 0xffc00000, 0x0, 0xffffffff +}; + + +int main() { + unsigned i; + + for(i = 0; i < LENGTH(test); i ++) { + nemu_assert((test[i] >> 7) == srl_ans[i]); + } + + for(i = 0; i < LENGTH(test); i ++) { + nemu_assert((unsigned)((int)test[i] >> (i + 4)) == srav_ans[i]); + } + + for(i = 0; i < LENGTH(test); i ++) { + nemu_assert((test[i] >> (i + 4)) == srlv_ans[i]); + } + + return 0; +} diff --git a/cpu-tests/tests/shuixianhua.c b/cpu-tests/tests/shuixianhua.c new file mode 100644 index 0000000..510ce0a --- /dev/null +++ b/cpu-tests/tests/shuixianhua.c @@ -0,0 +1,26 @@ +#include "trap.h" + +int ans[] = {153, 370, 371, 407}; + +int cube(int n) { + return n * n * n; +} + +int main() { + int n, n2, n1, n0; + int k = 0; + for(n = 100; n < 500; n ++) { + n2 = n / 100; + n1 = (n / 10) % 10; + n0 = n % 10; + + if(n == cube(n2) + cube(n1) + cube(n0)) { + nemu_assert(n == ans[k]); + k ++; + } + } + + nemu_assert(k == 4); + + return 0; +} diff --git a/cpu-tests/tests/string.c b/cpu-tests/tests/string.c new file mode 100644 index 0000000..912af66 --- /dev/null +++ b/cpu-tests/tests/string.c @@ -0,0 +1,27 @@ +#include "trap.h" + +char *s[] = { + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + ", World!\n", + "Hello, World!\n", + "#####" +}; + +char str1[] = "Hello"; +char str[20]; + +int main() { + nemu_assert(strcmp(s[0], s[2]) == 0); + nemu_assert(strcmp(s[0], s[1]) == -1); + nemu_assert(strcmp(s[0] + 1, s[1] + 1) == -1); + nemu_assert(strcmp(s[0] + 2, s[1] + 2) == -1); + nemu_assert(strcmp(s[0] + 3, s[1] + 3) == -1); + + nemu_assert(strcmp( strcat(strcpy(str, str1), s[3]), s[4]) == 0); + + nemu_assert(memcmp(memset(str, '#', 5), s[5], 5) == 0); + + return 0; +} diff --git a/cpu-tests/tests/sub-longlong.c b/cpu-tests/tests/sub-longlong.c new file mode 100644 index 0000000..2b86fae --- /dev/null +++ b/cpu-tests/tests/sub-longlong.c @@ -0,0 +1,22 @@ +#include "trap.h" + +long long sub(long long a, long long b) { + long long c = a - b; + return c; +} + +long long test_data[] = {0, 1, 2, 0x7fffffffffffffffLL, 0x8000000000000000LL, 0x8000000000000001LL, 0xfffffffffffffffeLL, 0xffffffffffffffffLL}; +long long ans[] = {0LL, 0xffffffffffffffffLL, 0xfffffffffffffffeLL, 0x8000000000000001LL, 0x8000000000000000LL, 0x7fffffffffffffffLL, 0x2LL, 0x1LL, 0x1LL, 0LL, 0xffffffffffffffffLL, 0x8000000000000002LL, 0x8000000000000001LL, 0x8000000000000000LL, 0x3LL, 0x2LL, 0x2LL, 0x1LL, 0LL, 0x8000000000000003LL, 0x8000000000000002LL, 0x8000000000000001LL, 0x4LL, 0x3LL, 0x7fffffffffffffffLL, 0x7ffffffffffffffeLL, 0x7ffffffffffffffdLL, 0LL, 0xffffffffffffffffLL, 0xfffffffffffffffeLL, 0x8000000000000001LL, 0x8000000000000000LL, 0x8000000000000000LL, 0x7fffffffffffffffLL, 0x7ffffffffffffffeLL, 0x1LL, 0LL, 0xffffffffffffffffLL, 0x8000000000000002LL, 0x8000000000000001LL, 0x8000000000000001LL, 0x8000000000000000LL, 0x7fffffffffffffffLL, 0x2LL, 0x1LL, 0LL, 0x8000000000000003LL, 0x8000000000000002LL, 0xfffffffffffffffeLL, 0xfffffffffffffffdLL, 0xfffffffffffffffcLL, 0x7fffffffffffffffLL, 0x7ffffffffffffffeLL, 0x7ffffffffffffffdLL, 0LL, 0xffffffffffffffffLL, 0xffffffffffffffffLL, 0xfffffffffffffffeLL, 0xfffffffffffffffdLL, 0x8000000000000000LL, 0x7fffffffffffffffLL, 0x7ffffffffffffffeLL, 0x1LL, 0LL}; + +#define NR_DATA LENGTH(test_data) + +int main() { + int i, j, ans_idx = 0; + for(i = 0; i < NR_DATA; i ++) { + for(j = 0; j < NR_DATA; j ++) { + nemu_assert(sub(test_data[i], test_data[j]) == ans[ans_idx ++]); + } + } + + return 0; +} diff --git a/cpu-tests/tests/sum.c b/cpu-tests/tests/sum.c new file mode 100644 index 0000000..64b2e20 --- /dev/null +++ b/cpu-tests/tests/sum.c @@ -0,0 +1,14 @@ +#include "trap.h" + +int main() { + int i = 1; + volatile int sum = 0; + while(i <= 100) { + sum += i; + i ++; + } + + nemu_assert(sum == 5050); + + return 0; +} diff --git a/cpu-tests/tests/switch.c b/cpu-tests/tests/switch.c new file mode 100644 index 0000000..9455328 --- /dev/null +++ b/cpu-tests/tests/switch.c @@ -0,0 +1,29 @@ +#include "trap.h" + +int switch_case(int n) { + int ret; + switch(n) { + case 0: ret = 0; break; + case 1: ret = 2; break; + case 2: case 3: ret = 5; break; + case 4: case 5: case 6: case 7: ret = 8; break; + case 8: case 9: case 10: case 11: ret = 10; break; + case 12: ret = 15; break; + default: ret = -1; break; + } + + return ret; +} + +int ans[] = {-1, 0, 2, 5, 5, 8, 8, 8, 8, 10, 10, 10, 10, 15, -1}; + +int main() { + int i; + for(i = 0; i < 15; i ++) { + nemu_assert(switch_case(i - 1) == ans[i]); + } + + nemu_assert(i == 15); + + return 0; +} diff --git a/cpu-tests/tests/to-lower-case.c b/cpu-tests/tests/to-lower-case.c new file mode 100644 index 0000000..edc6ed8 --- /dev/null +++ b/cpu-tests/tests/to-lower-case.c @@ -0,0 +1,18 @@ +#include "trap.h" + +char to_lower_case(char c) { + return (c >= 'A' && c <= 'Z' ? (c + 32) : c); +} + +volatile char ans [] = {0, 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, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; + +int main() { + int i; + for(i = 0; i < 128; i ++) { + nemu_assert(to_lower_case(i) == ans[i]); + } + + return 0; +} diff --git a/cpu-tests/tests/unalign.c b/cpu-tests/tests/unalign.c new file mode 100644 index 0000000..48d7326 --- /dev/null +++ b/cpu-tests/tests/unalign.c @@ -0,0 +1,18 @@ +#include "trap.h" + +volatile unsigned x = 0xffffffff; +volatile unsigned char buf[16]; + +int main() { + + for(int i = 0; i < 4; i++) { + *((volatile unsigned*)(buf + 3)) = 0xaabbccdd; + + x = *((volatile unsigned*)(buf + 3)); + nemu_assert(x == 0xaabbccdd); + + buf[0] = buf[1] = 0; + } + + return 0; +} diff --git a/cpu-tests/tests/wanshu.c b/cpu-tests/tests/wanshu.c new file mode 100644 index 0000000..9c384f0 --- /dev/null +++ b/cpu-tests/tests/wanshu.c @@ -0,0 +1,24 @@ +#include "trap.h" + +int ans[] = {6, 28}; + +int main() { + int n, sum, i, k = 0; + for(n = 1; n < 30; n ++) { + sum = 0; + for(i = 1; i < n; i ++) { + if(n % i == 0) { + sum += i; + } + } + + if(sum == n) { + nemu_assert(n == ans[k]); + k ++; + } + } + + nemu_assert(k == 2); + + return 0; +}