implemented flag for comparison result
This commit is contained in:
parent
ba72dae68f
commit
cf5ed7b601
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/bin/tcpu",
|
"program": "${workspaceFolder}/bin/tcpu",
|
||||||
"windows": { "program": "${workspaceFolder}/bin/tcpu.exe" },
|
"windows": { "program": "${workspaceFolder}/bin/tcpu.exe" },
|
||||||
"args": [ "-c", "../examples/conditional_jump.tasm", "o.bin", "--debug", "-i", "o.bin" ],
|
"args": [ "-c", "../examples/loop.tasm", "o.bin", "--debug", "-i", "o.bin" ],
|
||||||
"cwd": "${workspaceFolder}/bin",
|
"cwd": "${workspaceFolder}/bin",
|
||||||
"preLaunchTask": "build_exec_dbg",
|
"preLaunchTask": "build_exec_dbg",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
|
|||||||
@ -43,7 +43,7 @@ Machine code interpreter written in pure C. Can execute programs up to 1 MEGABYT
|
|||||||
| EXIT | | stop the program with exit code in `eax` |
|
| EXIT | | stop the program with exit code in `eax` |
|
||||||
| SYS | | call system function |
|
| SYS | | call system function |
|
||||||
| |
|
| |
|
||||||
| MOVC | `dst_register`, `value` | push constant value into `dst_register` |
|
| MOVC | `dst_register`, `const_value` | push constant value into `dst_register` |
|
||||||
| MOVR | `dst_register`, `src_register` | copy value from `src_register` to `dst_register` |
|
| MOVR | `dst_register`, `src_register` | copy value from `src_register` to `dst_register` |
|
||||||
| |
|
| |
|
||||||
| ADD | `dst_register`, `src_register` | `dst += src` |
|
| ADD | `dst_register`, `src_register` | `dst += src` |
|
||||||
@ -65,9 +65,9 @@ Machine code interpreter written in pure C. Can execute programs up to 1 MEGABYT
|
|||||||
| XOR | `dst_register`, `src_register` | `dst = dst ^ src` |
|
| XOR | `dst_register`, `src_register` | `dst = dst ^ src` |
|
||||||
| AND | `dst_register`, `src_register` | `dst = dst & src` |
|
| AND | `dst_register`, `src_register` | `dst = dst & src` |
|
||||||
| |
|
| |
|
||||||
| JMP | `dst_register` | goto `dst` |
|
| JMP | `dst_address_const` | goto `dst` |
|
||||||
| JNZ | `dst_register` | if (`cmp_flag` != 0) goto `dst` |
|
| JNZ | `dst_address_const` | if (`cmp_flag` != 0) goto `dst` |
|
||||||
| JZ | `dst_register` | if (`cmp_flag` == 0) goto `dst` |
|
| JZ | `dst_address_const` | if (`cmp_flag` == 0) goto `dst` |
|
||||||
|
|
||||||
### System functions
|
### System functions
|
||||||
To call a system function you need to push values to registers and write `SYS` opcode. The return value of a function will will be avaliable in `ax` after call.
|
To call a system function you need to push values to registers and write `SYS` opcode. The return value of a function will will be avaliable in `ax` after call.
|
||||||
|
|||||||
@ -5,9 +5,9 @@ Example of behavior change depending on some condition
|
|||||||
.main:
|
.main:
|
||||||
movc ax 1
|
movc ax 1
|
||||||
movc bx 2
|
movc bx 2
|
||||||
gt cx ax bx
|
gt ax bx
|
||||||
jnz @true cx
|
jnz @true
|
||||||
jz @false cx
|
jz @false
|
||||||
|
|
||||||
.true:
|
.true:
|
||||||
const8 true.msg "true\n"
|
const8 true.msg "true\n"
|
||||||
|
|||||||
@ -3,6 +3,7 @@ Example of self-repeating code section
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
.main:
|
.main:
|
||||||
|
movc dx 0; // loop counter
|
||||||
|
|
||||||
.loop
|
.loop
|
||||||
const8 datum "ITERATION!!! "
|
const8 datum "ITERATION!!! "
|
||||||
@ -11,4 +12,11 @@ movc ah 1
|
|||||||
movc rbx @datum
|
movc rbx @datum
|
||||||
movc ecx #datum
|
movc ecx #datum
|
||||||
sys
|
sys
|
||||||
jmp @loop
|
|
||||||
|
movc cx 1
|
||||||
|
add dx cx
|
||||||
|
movc cx 8
|
||||||
|
lt dx cx
|
||||||
|
jnz @loop
|
||||||
|
movc rax 0
|
||||||
|
exit
|
||||||
|
|||||||
@ -30,6 +30,10 @@ typedef struct VM {
|
|||||||
};
|
};
|
||||||
Register array[4];
|
Register array[4];
|
||||||
} registers;
|
} registers;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool cmp; // result of comparison operation
|
||||||
|
} flags;
|
||||||
|
|
||||||
VMState state;
|
VMState state;
|
||||||
char* NULLABLE(error_message); // not null on if state == VMState_InternalError
|
char* NULLABLE(error_message); // not null on if state == VMState_InternalError
|
||||||
|
|||||||
@ -11,40 +11,26 @@ i32 JMP_impl(VM* vm){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// JNZ [destination address] [condition register]
|
// JNZ [destination address]
|
||||||
i32 JNZ_impl(VM* vm){
|
i32 JNZ_impl(VM* vm){
|
||||||
u64 dst_addr = 0;
|
u64 dst_addr = 0;
|
||||||
readVar(dst_addr);
|
readVar(dst_addr);
|
||||||
|
|
||||||
RegisterCode reg_code = 0;
|
if(vm->flags.cmp != 0){
|
||||||
readRegisterCode(reg_code);
|
|
||||||
u64 cond_reg_value = 0;
|
|
||||||
VM_registerRead(vm, &cond_reg_value, reg_code);
|
|
||||||
|
|
||||||
if(cond_reg_value != 0){
|
|
||||||
vm->current_pos = dst_addr;
|
vm->current_pos = dst_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sizeof(dst_addr) + sizeof(reg_code);
|
return sizeof(dst_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JZ [destination address] [condition register]
|
// JZ [destination address]
|
||||||
i32 JZ_impl(VM* vm){
|
i32 JZ_impl(VM* vm){
|
||||||
u64 dst_addr = 0;
|
u64 dst_addr = 0;
|
||||||
{
|
readVar(dst_addr);
|
||||||
if(!VM_dataRead(vm, &dst_addr, vm->current_pos, sizeof(dst_addr)))
|
|
||||||
return -1;
|
|
||||||
vm->current_pos += sizeof(dst_addr);
|
|
||||||
};
|
|
||||||
|
|
||||||
RegisterCode reg_code = 0;
|
if(vm->flags.cmp == 0){
|
||||||
readRegisterCode(reg_code);
|
|
||||||
u64 cond_reg_value = 0;
|
|
||||||
VM_registerRead(vm, &cond_reg_value, reg_code);
|
|
||||||
|
|
||||||
if(cond_reg_value == 0){
|
|
||||||
vm->current_pos = dst_addr;
|
vm->current_pos = dst_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sizeof(dst_addr) + sizeof(reg_code);
|
return sizeof(dst_addr);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,18 +45,15 @@ i32 NAME##_impl (VM* vm) {\
|
|||||||
return sizeof(dst_reg_code) + sizeof(src_reg_code);\
|
return sizeof(dst_reg_code) + sizeof(src_reg_code);\
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPERATOR_IMPL_3(NAME, OPERATOR)\
|
#define OPERATOR_IMPL_CMP_FLAG(NAME, OPERATOR)\
|
||||||
i32 NAME##_impl (VM* vm) {\
|
i32 NAME##_impl (VM* vm) {\
|
||||||
RegisterCode dst_reg_code = 0, src0_reg_code = 0, src1_reg_code = 0;\
|
RegisterCode src0_reg_code = 0, src1_reg_code = 0;\
|
||||||
readRegisterCode(dst_reg_code);\
|
|
||||||
readRegisterCode(src0_reg_code);\
|
readRegisterCode(src0_reg_code);\
|
||||||
readRegisterCode(src1_reg_code);\
|
readRegisterCode(src1_reg_code);\
|
||||||
u64 dst_reg_value = 0, src0_reg_value = 0, src1_reg_value = 0;\
|
u64 src0_reg_value = 0, src1_reg_value = 0;\
|
||||||
VM_registerRead(vm, &dst_reg_value, dst_reg_code);\
|
|
||||||
VM_registerRead(vm, &src0_reg_value, src0_reg_code);\
|
VM_registerRead(vm, &src0_reg_value, src0_reg_code);\
|
||||||
VM_registerRead(vm, &src1_reg_value, src1_reg_code);\
|
VM_registerRead(vm, &src1_reg_value, src1_reg_code);\
|
||||||
\
|
\
|
||||||
dst_reg_value = src0_reg_value OPERATOR src1_reg_value;\
|
vm->flags.cmp = src0_reg_value OPERATOR src1_reg_value;\
|
||||||
VM_registerWrite(vm, &dst_reg_value, dst_reg_code);\
|
return sizeof(src0_reg_code) + sizeof(src1_reg_code);\
|
||||||
return sizeof(dst_reg_code) + sizeof(src0_reg_code) + sizeof(src1_reg_code);\
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,20 +17,20 @@ OPERATOR_IMPL_2(XOR, ^)
|
|||||||
OPERATOR_IMPL_2(AND, &)
|
OPERATOR_IMPL_2(AND, &)
|
||||||
|
|
||||||
|
|
||||||
/// EQ [dst_register] [src0_register] [src1_register]
|
/// EQ [src0_register] [src1_register]
|
||||||
OPERATOR_IMPL_3(EQ, ==)
|
OPERATOR_IMPL_CMP_FLAG(EQ, ==)
|
||||||
|
|
||||||
/// NE [dst_register] [src0_register] [src1_register]
|
/// NE [src0_register] [src1_register]
|
||||||
OPERATOR_IMPL_3(NE, !=)
|
OPERATOR_IMPL_CMP_FLAG(NE, !=)
|
||||||
|
|
||||||
/// LT [dst_register] [src0_register] [src1_register]
|
/// LT [src0_register] [src1_register]
|
||||||
OPERATOR_IMPL_3(LT, <)
|
OPERATOR_IMPL_CMP_FLAG(LT, <)
|
||||||
|
|
||||||
/// LE [dst_register] [src0_register] [src1_register]
|
/// LE [src0_register] [src1_register]
|
||||||
OPERATOR_IMPL_3(LE, <=)
|
OPERATOR_IMPL_CMP_FLAG(LE, <=)
|
||||||
|
|
||||||
/// GT [dst_register] [src0_register] [src1_register]
|
/// GT [src0_register] [src1_register]
|
||||||
OPERATOR_IMPL_3(GT, >)
|
OPERATOR_IMPL_CMP_FLAG(GT, >)
|
||||||
|
|
||||||
/// GE [dst_register] [src0_register] [src1_register]
|
/// GE [src0_register] [src1_register]
|
||||||
OPERATOR_IMPL_3(GE, >=)
|
OPERATOR_IMPL_CMP_FLAG(GE, >=)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user