comparisons & jumps

This commit is contained in:
julianb0 2019-05-16 19:49:51 +02:00
parent cedd8df711
commit 826ad2245e
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
8 changed files with 256 additions and 5 deletions

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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")

View File

@ -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;

View File

@ -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;

View File

@ -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,