basic test framework; MOV and ADD tests

master
Clyne 3 years ago
parent 7737afa6c2
commit fa1c2a97da

1
.gitignore vendored

@ -1,2 +1,3 @@
*.sw*
*.a *.a
*.o *.o

@ -116,13 +116,13 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode)
// ADD // ADD
uint32_t res = *src + *dst; uint32_t res = *src + *dst;
uint16_t sr = 0; uint16_t sr = 0;
if ((int16_t)res < 0) if ((int16_t)(res & 0xFFFF) < 0)
sr |= MSP430_SR_N; sr |= MSP430_SR_N;
if (res == 0) if ((res & 0xFFFF) == 0)
sr |= MSP430_SR_Z; sr |= MSP430_SR_Z;
if ((res & 0xFFFF0000) != 0) if ((res & 0xFFFF0000) != 0)
sr |= MSP430_SR_C; sr |= MSP430_SR_C;
if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000))
sr |= MSP430_SR_V; sr |= MSP430_SR_V;
*dst = (uint16_t)res; *dst = (uint16_t)res;
state->reg[2] = sr; state->reg[2] = sr;
@ -137,7 +137,7 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode)
sr |= MSP430_SR_Z; sr |= MSP430_SR_Z;
if ((res & 0xFFFF0000) != 0) if ((res & 0xFFFF0000) != 0)
sr |= MSP430_SR_C; sr |= MSP430_SR_C;
if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000))
sr |= MSP430_SR_V; sr |= MSP430_SR_V;
*dst = (uint16_t)res; *dst = (uint16_t)res;
state->reg[2] = sr; state->reg[2] = sr;
@ -152,7 +152,7 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode)
sr |= MSP430_SR_Z; sr |= MSP430_SR_Z;
if ((res & 0xFFFF0000) != 0) if ((res & 0xFFFF0000) != 0)
sr |= MSP430_SR_C; sr |= MSP430_SR_C;
if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000))
sr |= MSP430_SR_V; sr |= MSP430_SR_V;
*dst = (uint16_t)res; *dst = (uint16_t)res;
state->reg[2] = sr; state->reg[2] = sr;
@ -167,7 +167,7 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode)
sr |= MSP430_SR_Z; sr |= MSP430_SR_Z;
if ((res & 0xFFFF0000) != 0) // TODO confirm if ((res & 0xFFFF0000) != 0) // TODO confirm
sr |= MSP430_SR_C; sr |= MSP430_SR_C;
if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000))
sr |= MSP430_SR_V; sr |= MSP430_SR_V;
*dst = (uint16_t)res; *dst = (uint16_t)res;
state->reg[2] = sr; state->reg[2] = sr;
@ -182,7 +182,7 @@ int msp430_do_cycle_dual_operand(msp430_t *state, uint16_t opcode)
sr |= MSP430_SR_Z; sr |= MSP430_SR_Z;
if ((res & 0xFFFF0000) != 0) if ((res & 0xFFFF0000) != 0)
sr |= MSP430_SR_C; sr |= MSP430_SR_C;
if (((*src & 0x8000) ^ (*src & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000)) if (((*src & 0x8000) ^ (*dst & 0x8000)) == 0 && (*src & 0x8000) != (res & 0x8000))
sr |= MSP430_SR_V; sr |= MSP430_SR_V;
state->reg[2] = sr; state->reg[2] = sr;
break; } break; }

@ -2,8 +2,13 @@ DEBUG := #-DDEBUG
LIB430COREDIR = .. LIB430COREDIR = ..
TEST_CSRC = test.c TEST_CSRC = \
TEST_OUT = $(patsubst %.c,%.o,$(TEST_CSRC)) mov_constants.s \
mov_addressing_dest.s \
mov_addressing_source.s \
add.s
TEST_OUT = $(patsubst %.c,%.o,$(patsubst %.s,%.o,$(TEST_CSRC)))
all: $(LIB430COREDIR)/lib430core.a $(TEST_OUT) all: $(LIB430COREDIR)/lib430core.a $(TEST_OUT)
@ -12,13 +17,26 @@ $(LIB430COREDIR)/lib430core.a:
.c.o: .c.o:
@echo "Testing" $< "..." @echo "Testing" $< "..."
@msp430-elf32-gcc -T../link.ld $< -o tmp.elf -nostdlib -lgcc -lc @msp430-elf32-gcc -T../link.ld -O0 -ggdb -g3 $< -o tmp.elf -nostdlib -lgcc -lc
@msp430-elf32-objcopy -Obinary tmp.elf tmp.bin
@echo "#define TESTBIN \\" > test.h
@od -t x1 tmp.bin | awk '{for (i=2; i<=NF; i++) printf "0x" $$i ", "}' >> test.h
@printf "\n#define TESTSIZE %u \n" $$(msp430-elf32-objdump tmp.elf -Dj .text | grep -E "^\s+[0-9a-fA-F]+:" | wc -l) >> test.h
@echo >> test.h
@gcc -Os -ggdb -g3 -Wall -W -pedantic $(DEBUG) -I../src -o tmp \
test_$< -L$(LIB430COREDIR) -l430core
@./tmp
@rm tmp.elf tmp.bin tmp test.h
.s.o:
@echo "Testing" $< "..."
@msp430-elf32-gcc -T../link.ld -O0 $< -o tmp.elf -nostdlib -lgcc -lc
@msp430-elf32-objcopy -Obinary tmp.elf tmp.bin @msp430-elf32-objcopy -Obinary tmp.elf tmp.bin
@echo "#define TESTBIN \\" > test.h @echo "#define TESTBIN \\" > test.h
@od -t x1 tmp.bin | awk '{for (i=2; i<=NF; i++) printf "0x" $$i ", "}' >> test.h @od -t x1 tmp.bin | awk '{for (i=2; i<=NF; i++) printf "0x" $$i ", "}' >> test.h
@printf "\n#define TESTSIZE %u \n" $$(msp430-elf32-objdump tmp.elf -Dj .text | grep -E "^\s+[0-9a-fA-F]+:" | wc -l) >> test.h @printf "\n#define TESTSIZE %u \n" $$(msp430-elf32-objdump tmp.elf -Dj .text | grep -E "^\s+[0-9a-fA-F]+:" | wc -l) >> test.h
@echo >> test.h @echo >> test.h
@gcc -Os -ggdb -g3 -Wall -W -pedantic $(DEBUG) -I../src -o tmp \ @gcc -Os -ggdb -g3 -Wall -W -pedantic $(DEBUG) -I../src -o tmp \
core_test.c -L$(LIB430COREDIR) -l430core test_$(patsubst %.s,%.c,$<) -L$(LIB430COREDIR) -l430core
@./tmp > log @./tmp
@rm log tmp.elf tmp.bin tmp test.h @rm tmp.elf tmp.bin tmp test.h

@ -0,0 +1,16 @@
main:
mov #13, r5
add #15, r5
mov r2, r12
mov #-7, r6
add #7, r6
mov r2, r13
mov #0xfffa, r7
add #0x001e, r7
mov r2, r14
mov #-32700, r8
add #-800, r8
mov r2, r15
mov #2, r9
add #-5, r9
ret

@ -0,0 +1,11 @@
main:
mov #64, r4
mov r4, r5
mov #42, r4
mov r4, @r5
mov r4, 4(r5)
mov #50, mem
mov &mem, &0x50
ret
mem: .byte 5

@ -0,0 +1,14 @@
main:
mov #42, &0x40
mov #44, &0x42
mov #46, &0x44
mov #0x40, r4
mov r4, r5
mov 4(r5), r6
mov @r5+, r7
mov @r5, r8
mov var, r9
mov &0x44, r10
ret
var: .byte 13

@ -0,0 +1,8 @@
main:
mov #0, r4
mov #1, r5
mov #2, r6
mov #-1, r7
mov #4, r8
mov #8, r9
ret

@ -1,8 +0,0 @@
int main()
{
volatile int *mem = (int *)0x200;
*mem = 24;
for (int i = 0; i < 8; ++i)
*mem += 2;
return *mem;
}

@ -0,0 +1,53 @@
#include "core.h"
#include "test.h"
#include <stdio.h>
static uint8_t mem[0x10000] = {
TESTBIN
};
static void dump_state(msp430_t *state)
{
puts("MSP430 dump state:");
printf("R0/PC: 0x%04x R1/SP: 0x%04x R2/SR: 0x%04x R3: 0x%04x\n",
state->reg[0], state->reg[1], state->reg[2], state->reg[3]);
printf("R4: 0x%04x R5: 0x%04x R6: 0x%04x R7: 0x%04x\n",
state->reg[4], state->reg[5], state->reg[6], state->reg[7]);
printf("R8: 0x%04x R9: 0x%04x R10: 0x%04x R11: 0x%04x\n",
state->reg[8], state->reg[9], state->reg[10], state->reg[11]);
printf("R12: 0x%04x R13: 0x%04x R14: 0x%04x R15: 0x%04x\n\n",
state->reg[12], state->reg[13], state->reg[14], state->reg[15]);
}
int main()
{
msp430_t state;
msp430_init_state(&state, mem);
int r;
do {
r = msp430_do_cycle(&state);
if (r < 0) {
printf("Failed to execute near PC=0x%04x!\n", state.reg[0]);
return 1;
}
} while (r != 1);
if (state.reg[5] != 28 ||
state.reg[6] != 0 ||
state.reg[7] != 0x18 ||
state.reg[8] != 0x7d24 ||
state.reg[9] != 0xfffd ||
state.reg[12] != 0 ||
state.reg[13] != 0x03 ||
state.reg[14] != 0x01 ||
state.reg[15] != 0x101)
{
dump_state(&state);
return 1;
}
return 0;
}

@ -0,0 +1,50 @@
#include "core.h"
#include "test.h"
#include <stdio.h>
static uint8_t mem[0x10000] = {
TESTBIN
};
/*
static void dump_state(msp430_t *state)
{
puts("MSP430 dump state:");
printf("R0/PC: 0x%04x R1/SP: 0x%04x R2/SR: 0x%04x R3: 0x%04x\n",
state->reg[0], state->reg[1], state->reg[2], state->reg[3]);
printf("R4: 0x%04x R5: 0x%04x R6: 0x%04x R7: 0x%04x\n",
state->reg[4], state->reg[5], state->reg[6], state->reg[7]);
printf("R8: 0x%04x R9: 0x%04x R10: 0x%04x R11: 0x%04x\n",
state->reg[8], state->reg[9], state->reg[10], state->reg[11]);
printf("R12: 0x%04x R13: 0x%04x R14: 0x%04x R15: 0x%04x\n\n",
state->reg[12], state->reg[13], state->reg[14], state->reg[15]);
}
*/
int main()
{
msp430_t state;
msp430_init_state(&state, mem);
int r;
do {
r = msp430_do_cycle(&state);
if (r < 0) {
printf("Failed to execute near PC=0x%04x!\n", state.reg[0]);
return 1;
}
} while (r != 1);
if (state.reg[4] != 42 ||
state.reg[5] != 64 ||
*((uint16_t *)(state.mem + 64)) != 42 ||
*((uint16_t *)(state.mem + 68)) != 42 ||
*((uint16_t *)(state.mem + 0x50)) != 50)
{
return 1;
}
//dump_state(&state);
return 0;
}

@ -3,9 +3,10 @@
#include <stdio.h> #include <stdio.h>
//#define DEBUG static uint8_t mem[0x10000] = {
TESTBIN
};
#ifdef DEBUG
static void dump_state(msp430_t *state) static void dump_state(msp430_t *state)
{ {
puts("MSP430 dump state:"); puts("MSP430 dump state:");
@ -18,34 +19,33 @@ static void dump_state(msp430_t *state)
printf("R12: 0x%04x R13: 0x%04x R14: 0x%04x R15: 0x%04x\n\n", printf("R12: 0x%04x R13: 0x%04x R14: 0x%04x R15: 0x%04x\n\n",
state->reg[12], state->reg[13], state->reg[14], state->reg[15]); state->reg[12], state->reg[13], state->reg[14], state->reg[15]);
} }
#endif // DEBUG
static uint8_t mem[0x10000] = {
TESTBIN
};
int main() int main()
{ {
msp430_t state; msp430_t state;
msp430_init_state(&state, mem); msp430_init_state(&state, mem);
#ifdef DEBUG
dump_state(&state);
#endif // DEBUG
int r; int r;
do { do {
r = msp430_do_cycle(&state); r = msp430_do_cycle(&state);
if (r < 0) { if (r < 0) {
printf("Failed to execute near PC=0x%04x!\n", state.reg[0]); printf("Failed to execute near PC=0x%04x!\n", state.reg[0]);
return 1; return 1;
//break;
} }
} while (r != 1);
#ifdef DEBUG if (state.reg[4] != 0x40 ||
state.reg[5] != 0x42 ||
state.reg[6] != 46 ||
state.reg[7] != 42 ||
state.reg[8] != 44 ||
state.reg[9] != 13 ||
state.reg[10] != 46)
{
dump_state(&state); dump_state(&state);
#endif // DEBUG return 1;
} while (r != 1); }
return 0; return 0;
} }

@ -0,0 +1,36 @@
#include "core.h"
#include "test.h"
#include <stdio.h>
static uint8_t mem[0x10000] = {
TESTBIN
};
int main()
{
msp430_t state;
msp430_init_state(&state, mem);
int r;
do {
r = msp430_do_cycle(&state);
if (r < 0) {
printf("Failed to execute near PC=0x%04x!\n", state.reg[0]);
return 1;
}
} while (r != 1);
if (state.reg[4] != 0 ||
state.reg[5] != 1 ||
state.reg[6] != 2 ||
state.reg[7] != 0xFFFF ||
state.reg[8] != 4 ||
state.reg[9] != 8)
{
return 1;
}
return 0;
}
Loading…
Cancel
Save