mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
comparisons & jumps
This commit is contained in:
parent
cedd8df711
commit
826ad2245e
4
Makefile
4
Makefile
@ -3,7 +3,9 @@
|
||||
|
||||
all: k.exe
|
||||
|
||||
src = instr/instrs.c karch/decd.c karch/main.c karch/regs.c karch/dump.c
|
||||
src = instr/instrs.c karch/decd.c karch/main.c karch/regs.c \
|
||||
karch/dump.c instr/jumps.c
|
||||
|
||||
obj = $(patsubst %.c,%.o,$(src))
|
||||
|
||||
%.o: %.c instrs/i_arch.h */*.h $(src)
|
||||
|
63
instr/INSTRS
63
instr/INSTRS
@ -81,6 +81,61 @@ inc m
|
||||
dec r
|
||||
dec m
|
||||
|
||||
#
|
||||
# Comparison instruction
|
||||
#
|
||||
|
||||
# Affects ZF and CF
|
||||
cmp r r
|
||||
cmp r i
|
||||
cmp r m
|
||||
cmp i r
|
||||
cmp i i
|
||||
cmp i m
|
||||
cmp m r
|
||||
cmp m i
|
||||
cmp m m
|
||||
|
||||
# Only affects ZF
|
||||
test r r
|
||||
test r i
|
||||
test r m
|
||||
test i r
|
||||
test i i
|
||||
test i m
|
||||
test m r
|
||||
test m i
|
||||
test m m
|
||||
|
||||
#
|
||||
# Jump instructions
|
||||
#
|
||||
|
||||
jmp r
|
||||
jmp i
|
||||
|
||||
jz r
|
||||
jz i
|
||||
jnz r
|
||||
jnz i
|
||||
je r
|
||||
je i
|
||||
jne r
|
||||
jne i
|
||||
|
||||
ja r
|
||||
ja i
|
||||
jae r
|
||||
jae i
|
||||
|
||||
jb r
|
||||
jb i
|
||||
jbe r
|
||||
jbe i
|
||||
|
||||
# Jump if RCX is 0
|
||||
#jcxz
|
||||
|
||||
#
|
||||
# Movement instructions
|
||||
#
|
||||
@ -99,6 +154,9 @@ xchg m r
|
||||
xchg m i
|
||||
xchg m m
|
||||
|
||||
lea r m
|
||||
lea m m
|
||||
|
||||
#
|
||||
# Stack manipulation instructions
|
||||
#
|
||||
@ -114,10 +172,15 @@ call m
|
||||
|
||||
ret
|
||||
|
||||
pushf
|
||||
|
||||
#
|
||||
# Supervisor only instructions
|
||||
#
|
||||
|
||||
popf
|
||||
|
||||
cli
|
||||
sti
|
||||
stop
|
||||
|
||||
|
106
instr/instrs.c
106
instr/instrs.c
@ -12,6 +12,10 @@ IMPL_START_0(nop)
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//
|
||||
// Logical instructions
|
||||
//
|
||||
|
||||
IMPL_START_2(and)
|
||||
{
|
||||
v1 &= v2;
|
||||
@ -48,6 +52,10 @@ IMPL_START_1(not)
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//
|
||||
// Unsigned arithmetic instructions
|
||||
//
|
||||
|
||||
IMPL_START_2(add)
|
||||
{
|
||||
v1 += v2;
|
||||
@ -105,6 +113,46 @@ IMPL_START_1(dec)
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//
|
||||
// Comparison instructions
|
||||
//
|
||||
|
||||
IMPL_START_2(cmp)
|
||||
{
|
||||
if (v1 == v2) {
|
||||
ctx->r[FLG].val |= ZF;
|
||||
ctx->r[FLG].val &= ~CF;
|
||||
}
|
||||
|
||||
else if (v1 < v2) {
|
||||
ctx->r[FLG].val &= ~ZF;
|
||||
ctx->r[FLG].val |= CF;
|
||||
}
|
||||
|
||||
else {
|
||||
ctx->r[FLG].val &= ~ZF;
|
||||
ctx->r[FLG].val &= ~CF;
|
||||
}
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_2(test)
|
||||
{
|
||||
ulong v = v1 & v2;
|
||||
|
||||
if (v == 0) ctx->r[FLG].val |= ZF;
|
||||
else ctx->r[FLG].val &= ~ZF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//
|
||||
// Jump instructions
|
||||
//
|
||||
|
||||
//
|
||||
// Movement instructions
|
||||
//
|
||||
|
||||
IMPL_START_2(mov)
|
||||
{
|
||||
v1 = v2;
|
||||
@ -119,6 +167,18 @@ IMPL_START_2(xchg)
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_1(lea)
|
||||
{
|
||||
assert(p2->mem);
|
||||
|
||||
v1 = (p2->type == A_REG ? ctx->r[p2->val].val : p2->val) + p2->off;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//
|
||||
// Stack manipulation instructions
|
||||
//
|
||||
|
||||
IMPL_START_1(push)
|
||||
{
|
||||
if (ctx->r[RSP].val % 8 > 0 || ctx->r[RBP].val % 8 > 0) {
|
||||
@ -180,17 +240,59 @@ IMPL_START_0(ret)
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(pushf)
|
||||
{
|
||||
if (ctx->r[RSP].val % 8 > 0 || ctx->r[RBP].val % 8 > 0) {
|
||||
_except(ctx, E_STK, "Misaligned stack REGS");
|
||||
}
|
||||
|
||||
if (ctx->r[RSP].val > ctx->r[RBP].val) {
|
||||
_except(ctx, E_STK, "RSP above RBP");
|
||||
}
|
||||
|
||||
writemem64(ctx, ctx->r[FLG].val, ctx->r[RSP].val);
|
||||
ctx->r[RSP].val -= 8;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(popf)
|
||||
{
|
||||
if (ctx->r[RSP].val % 8 > 0 || ctx->r[RBP].val % 8 > 0) {
|
||||
_except(ctx, E_STK, "Misaligned stack REGS");
|
||||
}
|
||||
|
||||
if (ctx->r[RSP].val >= ctx->r[RBP].val) {
|
||||
_except(ctx, E_STK, "RBP above RSP");
|
||||
}
|
||||
|
||||
CHK_SUPERV(); // XXX
|
||||
|
||||
ctx->r[RSP].val += 8;
|
||||
ctx->r[FLG].val = readmem64(ctx, ctx->r[RSP].val);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//
|
||||
// Supervisor only instructions
|
||||
//
|
||||
|
||||
IMPL_START_0(cli)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
ctx->r[FLG].val &= ~(1L<<63);
|
||||
ctx->r[FLG].val &= ~IF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(sti)
|
||||
{
|
||||
CHK_SUPERV();
|
||||
ctx->r[FLG].val |= 1L<<63;
|
||||
ctx->r[FLG].val |= IF;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_0(stop)
|
||||
{
|
||||
_except(ctx, E_SHT, "STOP INSTR");
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
|
@ -41,7 +41,7 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
|
||||
|
||||
#define CHK_SUPERV() \
|
||||
do { \
|
||||
if ((ctx->r[FLG].val & (1L << 62)) == 1) { \
|
||||
if ((ctx->r[FLG].val & UF) == 1) { \
|
||||
_except(ctx, E_SYS, "Supervisor-only INSTR"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
@ -8,6 +8,8 @@ hd = open("instr/arch_i.h", "w")
|
||||
|
||||
count = 0
|
||||
|
||||
hd.write("// Auto-generated by instrs.py from INSTRS\n\n");
|
||||
|
||||
hd.write("#ifdef _NEED_ARCH_I\n")
|
||||
hd.write("instr_t arch_i[] =\n{\n\n")
|
||||
hd.write("#endif\n")
|
||||
|
@ -0,0 +1,67 @@
|
||||
// The OS/K Team licences this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#include "instrs.h"
|
||||
#include "arch_i.h"
|
||||
|
||||
IMPL_START_1(jmp)
|
||||
{
|
||||
ctx->r[RIP].val = v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jz)
|
||||
{
|
||||
if (ctx->r[FLG].val & ZF)
|
||||
ctx->r[RIP].val = v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jnz)
|
||||
{
|
||||
if (!(ctx->r[FLG].val & ZF))
|
||||
ctx->r[RIP].val = v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(je)
|
||||
{
|
||||
if (ctx->r[FLG].val & ZF)
|
||||
ctx->r[RIP].val = v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jne)
|
||||
{
|
||||
if (!(ctx->r[FLG].val & ZF))
|
||||
ctx->r[RIP].val = v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(ja)
|
||||
{
|
||||
if (!(ctx->r[FLG].val & ZF) && !(ctx->r[FLG].val & CF))
|
||||
ctx->r[RIP].val = v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jae)
|
||||
{
|
||||
if (!(ctx->r[FLG].val & CF))
|
||||
ctx->r[RIP].val = v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jb)
|
||||
{
|
||||
if (!(ctx->r[FLG].val & ZF) && ctx->r[FLG].val & CF)
|
||||
ctx->r[RIP].val = v1;
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(jbe)
|
||||
{
|
||||
if (ctx->r[FLG].val & CF)
|
||||
ctx->r[RIP].val = v1;
|
||||
}
|
||||
IMPL_END;
|
15
karch/arch.h
15
karch/arch.h
@ -46,6 +46,21 @@ enum
|
||||
SYS = 1 << 9, // Reserved for supervisor mode
|
||||
};
|
||||
|
||||
// FLG register
|
||||
enum
|
||||
{
|
||||
CF = 1 << 0, // Carry flag
|
||||
PF = 1 << 1, // Parity flag
|
||||
AC = 1 << 2, // Auxiliary flag
|
||||
ZF = 1 << 3, // Zero flag
|
||||
OV = 1 << 4, // Overflow flag
|
||||
DF = 1 << 5, // Direction flag
|
||||
SF = 1 << 6, // Sign flag
|
||||
|
||||
UF = 1 << 16, // User-mode flag
|
||||
IF = 1 << 17, // Interrupts enable flag
|
||||
};
|
||||
|
||||
struct reg_t
|
||||
{
|
||||
char *name;
|
||||
|
@ -10,7 +10,7 @@ ushort fwprog[] = {
|
||||
|
||||
I_CALL_I, A_IMM32, (MEMOFF+0x13)>>16, (MEMOFF+0x13)&0xFF,
|
||||
I_ADD_R_I, RAX, A_IMM16, 1,
|
||||
0xFFFF,
|
||||
I_STOP,
|
||||
|
||||
I_ADD_R_I, RBX, A_IMM16, 1,
|
||||
I_RET,
|
||||
|
Loading…
Reference in New Issue
Block a user