This commit is contained in:
julianb0 2019-07-11 18:34:21 +02:00
parent 42202788da
commit cec0afb0ee
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
37 changed files with 369 additions and 348 deletions

View File

@ -296,7 +296,10 @@ def parse_preproc(line):
sys.exit(1) sys.exit(1)
i = int(s, base=0) i = int(s, base=0)
i = i + (8 - i % 8)
if (i % 8) != 0:
i = i + (8 - i % 8)
written = b_data.write(bytearray(i)) written = b_data.write(bytearray(i))
assert(written == i) assert(written == i)
@ -334,9 +337,10 @@ def parse_preproc(line):
pdata += 1 pdata += 1
# align # align
for i in range(8 - len(s) % 8): if (len(s) % 8) != 0:
written = b_data.write(int(0).to_bytes(1, byteorder='little', signed=False)) for i in range(8 - len(s) % 8):
pdata += 1 written = b_data.write(int(0).to_bytes(1, byteorder='little', signed=False))
pdata += 1
pdefs[label + "_len"] = str(real_len) pdefs[label + "_len"] = str(real_len)
@ -756,7 +760,9 @@ special_syms = {
def gentext(): def gentext():
text_start = start_addr text_start = start_addr
data_start = text_start + ptext data_start = text_start + ptext
data_start += (8 - data_start % 8)
if (data_start % 8) != 0:
data_start += (8 - data_start % 8)
instrs.seek(0) instrs.seek(0)
@ -844,7 +850,9 @@ def sort_by_list(dict_, list_):
def gensym(): def gensym():
text_start = start_addr text_start = start_addr
data_start = text_start + ptext data_start = text_start + ptext
data_start += (8 - data_start % 8)
if (data_start % 8) != 0:
data_start += (8 - data_start % 8)
for label in plabels_text: for label in plabels_text:
plabels_text[label] += text_start plabels_text[label] += text_start
@ -864,10 +872,11 @@ def genout():
b_data.seek(0) b_data.seek(0)
b_out.write(b_text.read()) b_out.write(b_text.read())
data_align = (8 - ptext % 8) if (ptext % 8) != 0:
data_align = (8 - ptext % 8)
for i in range(data_align): for i in range(data_align):
b_out.write(int(0).to_bytes(1, byteorder='little', signed=False)) b_out.write(int(0).to_bytes(1, byteorder='little', signed=False))
b_out.write(b_data.read()) b_out.write(b_data.read())

View File

@ -1,33 +1,22 @@
inv inv
flg
rip eip ip
rpc epc pc
px0
px1
fc1 fc1
fc2
sa0 k0
sa1 k1
sa2 k2
sa3 k3
cr0 c0 cr0 c0
cr1 c1 cr1 c1
cr2 c2 cr2 c2
cr3 c3 cr3 c3
cr4 c4
trp tp
rax eax ax rx0 r0 rax ax r0
rbx ebx bx rx1 r1 rbx bx r1
rcx ecx cx rx2 r2 rcx cx r2
rdx edx dx rx3 r3 rdx dx r3
rsi esi si rx4 r4 rsi si r4
rdi edi di rx5 r5 rdi di r5
rbp ebp bp rx6 r6 rbp bp r6
rsp esp sp rx7 r7 rsp sp r7
rx8 r8 rfx fs r8
rx9 r9 rip ip r9
r10 r10
r11 r11
r12 r12
@ -35,36 +24,20 @@ r13
r14 r14
r15 r15
ax0 a0 ax0 a0 r16
ax1 a1 ax1 a1 r17
ax2 a2 ax2 a2 r18
ax3 a3 ax3 a3 r19
ax4 a4 ax4 a4 r20
ax5 a5 ax5 a5 r21
ax6 a6 ax6 a6 r22
ax7 a7 ax7 a7 r23
ax8 a8
ax9 a9
a10
a11
a12
a13
a14
a15
nx0 n0 nx0 n0 r24
nx1 n1 nx1 n1 r25
nx2 n2 nx2 n2 r26
nx3 n3 nx3 n3 r27
nx4 n4 nx4 n4 r28
nx5 n5 nx5 n5 r29
nx6 n6 nx6 n6 r30
nx7 n7 nx7 n7 r31
nx8 n8
nx9 n9
n10
n11
n12
n13
n14
n15

View File

@ -9,4 +9,5 @@ include "crt/limits.k"
include "crt/err/errno.k" include "crt/err/errno.k"
include "crt/fmt/format.k" include "crt/fmt/format.k"
include "crt/str/string.k" include "crt/str/string.k"
include "crt/lib/time.k"

View File

@ -20,7 +20,7 @@ utoa:
; ;
ltostr: ltostr:
mov rax, ax0 mov rax, ax0
xor rx8, rx8 xor r11, r11
; make sure base is in [2, 32] ; make sure base is in [2, 32]
b.b ax2, 2, .bad b.b ax2, 2, .bad
@ -35,9 +35,9 @@ ltostr:
cmp.nz ax2, 10 ; base 10 cmp.nz ax2, 10 ; base 10
j.nz .conv j.nz .conv
sgn rx8, ax1 ; extract ax1 sign sgn r11, ax1 ; extract ax1 sign
cmp rx8, -1 ; negative? cmp r11, -1 ; negative?
neg.z ax1, ax1 neg.z ax1, ax1
; main loop ; main loop
@ -63,7 +63,7 @@ ltostr:
; add minus flag, null-terminate and reverse ; add minus flag, null-terminate and reverse
.fini: .fini:
cmp rx8, -1 cmp r11, -1
mov.z b[ax0], '-' mov.z b[ax0], '-'
inc.z ax0 inc.z ax0

View File

@ -113,32 +113,32 @@ strtoq:
mov ax1, 8 mov ax1, 8
.main_loop: .main_loop:
movzx rx8, b[rdx] movzx r12, b[rdx]
inc rdx inc rdx
cmp rx8, '0' cmp r12, '0'
jmp.b .done jmp.b .done
cmp.ae rx8, '9' cmp.ae r12, '9'
sub.be rx8, '0' sub.be r12, '0'
jmp.be .next jmp.be .next
cmp rx8, 'A' cmp r12, 'A'
cmp.ae rx8, 'Z' cmp.ae r12, 'Z'
sub.be rx8, 55 ; 'A' - 10 sub.be r12, 55 ; 'A' - 10
jmp.be .next jmp.be .next
cmp rx8, 'a' cmp r12, 'a'
jmp.b .next jmp.b .next
cmp.ae rx8, 'z' cmp.ae r12, 'z'
sub.be rx8, 87 ; 'a' - 10 sub.be r12, 87 ; 'a' - 10
jmp.be .next jmp.be .next
.next: .next:
; too large for base? ; too large for base?
b.ae rx8, ax1, .done b.ae r12, ax1, .done
mul rax, ax1 mul rax, ax1
add rax, rx8 add rax, r12
jmp .main_loop jmp .main_loop
.done: .done:

83
ka/crt/lib/time.k Normal file
View File

@ -0,0 +1,83 @@
; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; struct TIME
; {
; byte sec; +0 (0-59)
; byte min; +1 (0-59)
; byte hour; +2 (0-23)
; byte mday; +3 (0-31)
; byte month; +4 (0-11)
; byte; +5 (pad)
; word year; +6 (0-65536)
; word yday; +8 (0-365)
; word; +10 (pad)
; dword; +12 (pad)
; } 16 bytes
;
;
; int DaysInYear(int year)
;
DaysInYear:
mov rax, 365
; divisible by 4?
rem rcx, ax0, 4
b.nz rcx, 0, .end
; divisible by 100?
rem rcx, ax0, 100
b.nz rcx, 0, .leap
; divisible by 400?
rem rcx, ax0, 400
b.nz rcx, 0, .end
.leap:
inc rax
.end:
ret
;
; TIME *GetTimeUTC(void)
;
GetTimeUTC:
ytime r11, r12, r13
mov rdx, .buf
; seconds
rem rcx, r11, 60
mov b[rdx], rcx
; minutes
div rcx, r11, 60
rem rcx, 60
mov b[rdx+1], rcx
; hours
div rcx, r11, 3600
rem rcx, 24
mov b[rdx+2], rcx
; month days
div rcx, r11, 3600*24
mov b[rdx+3], rcx
; month
mov b[rdx+4], r12
; years
mov w[rdx+6], r13
;
; ydays (TODO)
;
mov rax, .buf
ret
.buf = [24]

View File

@ -12,7 +12,7 @@ strrev:
ret.z ret.z
; save str's location ; save str's location
mov rx8, ax1 mov r10, ax1
; go to str's end, just before ; go to str's end, just before
; the null terminator ; the null terminator
@ -26,7 +26,7 @@ strrev:
mov rax, b[ax1] mov rax, b[ax1]
mov b[ax0], rax mov b[ax0], rax
cmp ax1, rx8 cmp ax1, r10
mov.z b[ax0+1], 0 mov.z b[ax0+1], 0
ret.z ret.z

View File

@ -63,7 +63,7 @@ trap0_handler:
call RFS.StoreReg call RFS.StoreReg
; No flags set ; No flags set
mov ax1, $flg mov ax1, $rfx
xor ax2, ax2 xor ax2, ax2
call RFS.StoreReg call RFS.StoreReg

View File

@ -83,11 +83,11 @@ main:
inc r11 inc r11
.next_space: .next_space:
mov rx8, b[r11] mov r10, b[r11]
b.z rx8, 0, .no_argv1 b.z r10, 0, .no_argv1
; skip spaces ; skip spaces
cmp rx8, ' ' cmp r10, ' '
inc.z r11 inc.z r11
jmp.z .next_space jmp.z .next_space
@ -115,6 +115,12 @@ main:
call strcmp call strcmp
b.z rax, 0, .handle_CLS b.z rax, 0, .handle_CLS
.builtin_date = "date"
mov ax0, argv0
mov ax1, .builtin_date
call strcmp
b.z rax, 0, .handle_DATE
.builtin_dir = "dir" .builtin_dir = "dir"
mov ax0, argv0 mov ax0, argv0
mov ax1, .builtin_dir mov ax1, .builtin_dir
@ -145,6 +151,12 @@ main:
call strcmp call strcmp
b.z rax, 0, .handle_PRINT b.z rax, 0, .handle_PRINT
.builtin_time = "time"
mov ax0, argv0
mov ax1, .builtin_time
call strcmp
b.z rax, 0, .handle_TIME
.builtin_ver = "ver" .builtin_ver = "ver"
mov ax0, argv0 mov ax0, argv0
mov ax1, .builtin_ver mov ax1, .builtin_ver
@ -176,6 +188,25 @@ main:
prn 0xC15000AF prn 0xC15000AF
jmp .print_prompt jmp .print_prompt
.handle_DATE:
time ax0
call GetTimeUTC
push b[rax+3]
mov rcx, b[rax+4]
inc rcx
push rcx
push w[rax+6]
mov ax0, .datefmt
call printf
add rsp, 8*5
jmp .print_prompt
.datefmt = "%d/%d/%d\n"
.handle_DIR: .handle_DIR:
call builtins.dir call builtins.dir
jmp .print_prompt jmp .print_prompt
@ -198,6 +229,21 @@ main:
.handle_PRINT: .handle_PRINT:
jmp .print_prompt jmp .print_prompt
.handle_TIME:
time ax0
call GetTimeUTC
push b[rax]
push b[rax+1]
push b[rax+2]
mov ax0, .timefmt
call printf
add rsp, 3*8
jmp .print_prompt
.timefmt = "%d:%d:%d\n"
.handle_VER: .handle_VER:
mov rcx, STRLEN_MAX mov rcx, STRLEN_MAX
mov rdx, cmd.versionstr mov rdx, cmd.versionstr
@ -213,6 +259,8 @@ main:
prns.rep.nz rdx prns.rep.nz rdx
mov rdx, .helpmsg.cls mov rdx, .helpmsg.cls
prns.rep.nz rdx prns.rep.nz rdx
mov rdx, .helpmsg.date
prns.rep.nz rdx
mov rdx, .helpmsg.dir mov rdx, .helpmsg.dir
prns.rep.nz rdx prns.rep.nz rdx
mov rdx, .helpmsg.echo mov rdx, .helpmsg.echo
@ -223,6 +271,8 @@ main:
prns.rep.nz rdx prns.rep.nz rdx
mov rdx, .helpmsg.print mov rdx, .helpmsg.print
prns.rep.nz rdx prns.rep.nz rdx
mov rdx, .helpmsg.time
prns.rep.nz rdx
mov rdx, .helpmsg.ver mov rdx, .helpmsg.ver
prns.rep.nz rdx prns.rep.nz rdx
@ -230,10 +280,12 @@ main:
.helpmsg = "The following commands are built-in:\n" .helpmsg = "The following commands are built-in:\n"
.helpmsg.cls = " CLS Clear screen\n" .helpmsg.cls = " CLS Clear screen\n"
.helpmsg.date = " DATE Display current date\n"
.helpmsg.dir = " DIR Print contents of current directory\n" .helpmsg.dir = " DIR Print contents of current directory\n"
.helpmsg.echo = " ECHO Write arguments to standard output\n" .helpmsg.echo = " ECHO Write arguments to standard output\n"
.helpmsg.exit = " EXIT Initiate machine shutdown\n" .helpmsg.exit = " EXIT Initiate machine shutdown\n"
.helpmsg.help = " HELP Show these messages\n" .helpmsg.help = " HELP Display these messages\n"
.helpmsg.print = " PRINT Show contents of text file\n" .helpmsg.print = " PRINT Display contents of text file\n"
.helpmsg.ver = " VER Show current COMMAND.COM and DOS kernel versions\n" .helpmsg.time = " TIME Display current time of day\n"
.helpmsg.ver = " VER Display current COMMAND.COM and DOS kernel versions\n"

View File

@ -6,7 +6,7 @@
verbose ?= yes verbose ?= yes
OBJDIR = ob OBJDIR = ob
FLAGS=-O2 -Wall -fno-builtin-log -I. FLAGS=-O2 -Wall -fno-builtin-log -I. -Werror=implicit-function-declaration
dv_src = $(shell ls dv/*.c) dv_src = $(shell ls dv/*.c)
in_src = $(shell ls in/*.c) in_src = $(shell ls in/*.c)

View File

@ -188,7 +188,7 @@ long cpudev_storereg(ctx_t *ctx, dev_t *dev)
if ((ushort)ax1 >= NREGS) if ((ushort)ax1 >= NREGS)
_except(ctx, E_UDF, "cpudev: register index out of range: #%u", ax1); _except(ctx, E_UDF, "cpudev: register index out of range: #%u", ax1);
rfs[ax0][ax1] = ax2; rfs[ax0][ax1] = R(AX2);
return 0; return 0;
} }

View File

@ -97,7 +97,10 @@ long diskdev_open(ctx_t *ctx, dev_t *dev)
tmp = open(buf, O_RDWR); tmp = open(buf, O_RDWR);
if (tmp < 0) if (tmp < 0)
{
perror("diskdev: open");
return -1; return -1;
}
disk->table[fd] = tmp; disk->table[fd] = tmp;
rax = fd; rax = fd;
@ -126,7 +129,7 @@ long diskdev_read(ctx_t *ctx, dev_t *dev)
{ {
GETDISK(); GETDISK();
if (ax0 >= MAXOPEN || disk->table[ax0] <= 0 || ax2 >= MAXRW) if (ax0 >= MAXOPEN || disk->table[ax0] <= 0 || R(AX2) >= MAXRW)
return -1; return -1;
int ret; int ret;
@ -135,7 +138,7 @@ long diskdev_read(ctx_t *ctx, dev_t *dev)
if (buf == NULL) if (buf == NULL)
return -1; return -1;
ret = read(disk->table[ax0], buf, ax2); ret = read(disk->table[ax0], buf, R(AX2));
if (ret < 0) if (ret < 0)
{ {

View File

@ -13,17 +13,6 @@
# #
break break
#
# Step-by-step execution (STEP)
#
# IF $1 == 0 THEN
# (disable step-by-step execution)
# ELSE
# (enable step-by-step execution)
# FI
#
step ri
# #
# Enable/disable instruction dumping (DUMP) # Enable/disable instruction dumping (DUMP)
# #

View File

@ -36,6 +36,13 @@ xpause
# #
time r time r
#
# $1 = seconds since start of month
# $2 = current month
# $3 = current year
#
ytime r r r
# #
# Get timestamp in µseconds # Get timestamp in µseconds
# #

View File

@ -86,12 +86,3 @@ rotl rm r r
# #
ldarg r r ldarg r r
#
# Get code/data offset (GCO/GCD)
#
# $1 = CR1 (GCO)
# $1 = CR2 (GCD)
#
gco r
gcd r

View File

@ -43,7 +43,7 @@ leave
# RSP = RSP - 8 # RSP = RSP - 8
# *RSP = $1 # *RSP = $1
# #
push ri push rim
# #
# POP value from stack # POP value from stack

View File

@ -88,28 +88,28 @@ IMPL_END;
IMPL_START_2(adc) IMPL_START_2(adc)
{ {
ALU_GET_SRCS(); ALU_GET_SRCS();
v1 = src1 + src2 + !!(flg&CF); v1 = src1 + src2 + !!(rfx&CF);
} }
IMPL_OUT; IMPL_OUT;
IMPL_START_2(ado) IMPL_START_2(ado)
{ {
ALU_GET_SRCS(); ALU_GET_SRCS();
v1 = src1 + src2 + !!(flg&OF); v1 = src1 + src2 + !!(rfx&OF);
} }
IMPL_OUT; IMPL_OUT;
IMPL_START_2(sbb) IMPL_START_2(sbb)
{ {
ALU_GET_SRCS(); ALU_GET_SRCS();
v1 = src1 - src2 - !!(flg&CF); v1 = src1 - src2 - !!(rfx&CF);
} }
IMPL_OUT; IMPL_OUT;
IMPL_START_2(sbo) IMPL_START_2(sbo)
{ {
ALU_GET_SRCS(); ALU_GET_SRCS();
v1 = src1 - src2 - !!(flg&OF); v1 = src1 - src2 - !!(rfx&OF);
} }
IMPL_OUT; IMPL_OUT;
@ -159,13 +159,13 @@ IMPL_START_2(mulf)
multiply(src1, src2, &v2, &v1); multiply(src1, src2, &v2, &v1);
if (v2 > 0) { if (v2 > 0) {
flg |= CF; rfx |= CF;
flg |= OF; rfx |= OF;
} }
else { else {
flg &= ~CF; rfx &= ~CF;
flg &= ~OF; rfx &= ~OF;
} }
} }
IMPL_OUT; IMPL_OUT;

View File

@ -16,12 +16,6 @@ IMPL_START_0(break)
} }
IMPL_END; IMPL_END;
IMPL_START_1(step)
{
ctx->step = !!v1;
}
IMPL_END;
IMPL_START_1(dump) IMPL_START_1(dump)
{ {
(void)v1; (void)v1;

View File

@ -8,14 +8,14 @@
IMPL_START_0(cli) IMPL_START_0(cli)
{ {
CHK_SUPERV(); CHK_SUPERV();
cr0 &= ~IF; R(CR0) &= ~IF;
} }
IMPL_END; IMPL_END;
IMPL_START_0(sti) IMPL_START_0(sti)
{ {
CHK_SUPERV(); CHK_SUPERV();
cr0 |= IF; R(CR0) |= IF;
} }
IMPL_END; IMPL_END;
@ -23,13 +23,13 @@ IMPL_END;
IMPL_START_0(cld) IMPL_START_0(cld)
{ {
flg &= ~DF; R(RFX) &= ~DF;
} }
IMPL_END; IMPL_END;
IMPL_START_0(std) IMPL_START_0(std)
{ {
flg |= DF; R(RFX) |= DF;
} }
IMPL_END; IMPL_END;
@ -37,19 +37,19 @@ IMPL_END;
IMPL_START_0(cmc) IMPL_START_0(cmc)
{ {
flg = (flg&CF ? flg&~CF : flg|CF); R(RFX) = (R(RFX)&CF ? R(RFX)&~CF : R(RFX)|CF);
} }
IMPL_END; IMPL_END;
IMPL_START_0(clc) IMPL_START_0(clc)
{ {
flg &= ~CF; R(RFX) &= ~CF;
} }
IMPL_END; IMPL_END;
IMPL_START_0(stc) IMPL_START_0(stc)
{ {
flg |= CF; R(RFX) |= CF;
} }
IMPL_END; IMPL_END;

View File

@ -4,13 +4,13 @@
#define PARITY(v) __builtin_parity(v) #define PARITY(v) __builtin_parity(v)
#define SET_ZF(v) \ #define SET_ZF(v) \
flg = ((v) == 0 ? (flg|ZF) : (flg&~ZF)) R(RFX) = ((v) == 0 ? (R(RFX)|ZF) : (R(RFX)&~ZF))
#define SET_SF(v) \ #define SET_SF(v) \
flg = ((long)(v) < 0 ? (flg|SF) : (flg&~SF)) R(RFX) = ((long)(v) < 0 ? (R(RFX)|SF) : (R(RFX)&~SF))
#define SET_PF(v) \ #define SET_PF(v) \
flg = (PARITY(v) == 1 ? (flg|PF) : (flg&~PF)) R(RFX) = (PARITY(v) == 1 ? (R(RFX)|PF) : (R(RFX)&~PF))
#define SET_ZSF(v) \ #define SET_ZSF(v) \
SET_ZF(v); \ SET_ZF(v); \
@ -25,12 +25,12 @@
ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \ ulong _u1 = (ulong)v1, _u2 = (ulong)v2; \
long _s1 = (long)v1, _s2 = (long)v2; \ long _s1 = (long)v1, _s2 = (long)v2; \
\ \
if (_u1 < _u2) flg |= CF; \ if (_u1 < _u2) R(RFX) |= CF; \
else flg &= ~CF; \ else R(RFX) &= ~CF; \
\ \
if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \ if ( ((_s1 < 0) && (_s1 > LONG_MAX + _s2)) \
|| ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \ || ((_s2 > 0) && (_s1 < LONG_MIN + _s2)) ) \
flg |= OF; \ R(RFX) |= OF; \
else flg &= ~OF; \ else R(RFX) &= ~OF; \
SET_ZSF(_u1 - _u2); SET_ZSF(_u1 - _u2);

View File

@ -26,11 +26,11 @@ IMPL_START_0(prns)
COMPARE(ch, 0); COMPARE(ch, 0);
if ((flg & ZF) == 0) if ((rfx & ZF) == 0)
{ {
console_putc(ctx, ch); console_putc(ctx, ch);
if (flg & DF) if (rfx & DF)
R(p1->reg)--; R(p1->reg)--;
else else
R(p1->reg)++; R(p1->reg)++;

View File

@ -94,7 +94,7 @@ IMPL_START_2(name) \
#define CHK_SUPERV() \ #define CHK_SUPERV() \
do { \ do { \
if ((cr0 & UF) > 0) { \ if ((R(CR0) & UF) > 0) { \
_except(ctx, E_SYS, "Supervisor-only INSTR"); \ _except(ctx, E_SYS, "Supervisor-only INSTR"); \
} \ } \
} while (0) } while (0)

View File

@ -7,21 +7,21 @@
IMPL_START_1(j) IMPL_START_1(j)
{ {
rip = v1; R(RIP) = v1;
} }
IMPL_END; IMPL_END;
IMPL_START_1(jmp) IMPL_START_1(jmp)
{ {
rip = v1; R(RIP) = v1;
} }
IMPL_END; IMPL_END;
IMPL_START_1(loop) IMPL_START_1(loop)
{ {
if (rcx > 0) { if (R(RCX) > 0) {
rcx--; R(RCX)--;
rip = v1; R(RIP) = v1;
} }
} }
IMPL_END; IMPL_END;
@ -33,7 +33,7 @@ IMPL_START_3(b)
COMPARE(v1, v2); COMPARE(v1, v2);
if (eval_cond(ctx, ctx->cond)) if (eval_cond(ctx, ctx->cond))
rip = v3; R(RIP) = v3;
} }
IMPL_END; IMPL_END;

View File

@ -13,7 +13,7 @@ IMPL_OUT;
IMPL_START_2(test) IMPL_START_2(test)
{ {
flg &= ~(CF|OF); rfx &= ~(CF|OF);
SET_ZSF(v1 & v2); SET_ZSF(v1 & v2);
} }
IMPL_END; IMPL_END;

View File

@ -44,6 +44,20 @@ IMPL_START_1(time)
} }
IMPL_OUT; IMPL_OUT;
IMPL_START_3(ytime)
{
time_t t = time(NULL);
struct tm *tm = localtime(&t);
v1 = tm->tm_sec + tm->tm_min * 60
+ tm->tm_hour * 60 * 60
+ tm->tm_mday * 60 * 60 * 24;
v2 = tm->tm_mon;
v3 = tm->tm_year + 1900;
}
IMPL_OUT_3;
IMPL_START_1(utime) IMPL_START_1(utime)
{ {
struct timeval time; struct timeval time;
@ -56,27 +70,27 @@ IMPL_OUT;
IMPL_START_0(cls) IMPL_START_0(cls)
{ {
rax = rbx = rcx = rdx = rdi = rsi = 0; R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
for (int i = RX8; i <= N15; i++) R(i) = 0; for (int i = R10; i <= NX7; i++) R(i) = 0;
} }
IMPL_END; IMPL_END;
IMPL_START_0(clr) IMPL_START_0(clr)
{ {
rax = rbx = rcx = rdx = rdi = rsi = 0; R(RAX) = R(RBX) = R(RCX) = R(RDX) = R(RDI) = R(RSI) = R(RFX) = 0;
for (int i = RX8; i <= R15; i++) R(i) = 0; for (int i = R10; i <= R15; i++) R(i) = 0;
} }
IMPL_END; IMPL_END;
IMPL_START_0(cla) IMPL_START_0(cla)
{ {
for (int i = AX0; i <= A15; i++) R(i) = 0; for (int i = AX0; i <= AX7; i++) R(i) = 0;
} }
IMPL_END; IMPL_END;
IMPL_START_0(cln) IMPL_START_0(cln)
{ {
for (int i = NX0; i <= N15; i++) R(i) = 0; for (int i = NX0; i <= NX7; i++) R(i) = 0;
} }
IMPL_END; IMPL_END;

View File

@ -60,12 +60,12 @@ IMPL_OUT_2;
IMPL_START_2(cmpxchg) IMPL_START_2(cmpxchg)
{ {
if (rax == v1) { if (rax == v1) {
flg |= ZF; rfx |= ZF;
v1 = v2; v1 = v2;
} }
else { else {
flg &= ~ZF; rfx &= ~ZF;
rax = v1; rax = v1;
} }
} }
@ -105,17 +105,3 @@ IMPL_OUT;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
IMPL_START_1(gco)
{
v1 = cr1;
}
IMPL_OUT;
IMPL_START_1(gcd)
{
v1 = cr2;
}
IMPL_OUT;
//----------------------------------------------------------------------------//

View File

@ -9,46 +9,46 @@
IMPL_START_1(push) IMPL_START_1(push)
{ {
rsp -= 8; R(RSP) -= 8;
writemem(ctx, v1, rsp, 8); writemem(ctx, v1, R(RSP), 8);
} }
IMPL_END; IMPL_END;
IMPL_START_1(pop) IMPL_START_1(pop)
{ {
v1 = readmem(ctx, rsp, 8); v1 = readmem(ctx, R(RSP), 8);
rsp += 8; R(RSP) += 8;
} }
IMPL_OUT; IMPL_OUT;
IMPL_START_1(call) IMPL_START_1(call)
{ {
rsp -= 8; R(RSP) -= 8;
writemem(ctx, rip, rsp, 8); writemem(ctx, R(RIP), R(RSP), 8);
rip = v1; R(RIP) = v1;
} }
IMPL_END; IMPL_END;
IMPL_START_0(ret) IMPL_START_0(ret)
{ {
rip = readmem(ctx, rsp, 8); R(RIP) = readmem(ctx, R(RSP), 8);
rsp += 8; R(RSP) += 8;
} }
IMPL_END; IMPL_END;
IMPL_START_0(enter) IMPL_START_0(enter)
{ {
writemem(ctx, rbp, rsp - 8, 8); writemem(ctx, R(RBP), R(RSP) - 8, 8);
rbp = rsp - 8; R(RBP) = R(RSP) - 8;
rsp -= (p1->val + 1) * 8; R(RSP) -= (p1->val + 1) * 8;
} }
IMPL_END; IMPL_END;
IMPL_START_0(leave) IMPL_START_0(leave)
{ {
rsp = rbp + 8; R(RSP) = R(RBP) + 8;
rbp = readmem(ctx, rbp, 8); R(RBP) = readmem(ctx, R(RBP), 8);
} }
IMPL_END; IMPL_END;

View File

@ -6,7 +6,7 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#define STR_MOVE(reg, len) \ #define STR_MOVE(reg, len) \
if ((flg & DF) == 0) \ if ((rfx & DF) == 0) \
R(reg) += len; \ R(reg) += len; \
else \ else \
R(reg) -= len; R(reg) -= len;
@ -52,7 +52,7 @@ static void lods_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
{ {
R(p1->reg) = readmem(ctx, R(p2->reg), len); R(p1->reg) = readmem(ctx, R(p2->reg), len);
flg = (R(p1->reg) == 0 ? flg|ZF : flg&~ZF); R(RFX) = (R(p1->reg) == 0 ? R(RFX)|ZF : R(RFX)&~ZF);
STR_MOVE(p2->reg, len); STR_MOVE(p2->reg, len);
} }
@ -91,10 +91,10 @@ static void scas_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
COMPARE(x, v2); COMPARE(x, v2);
if (x == 0) { if (x == 0) {
flg |= ZF; R(RFX) |= ZF;
} }
else if (!(flg&ZF)) { else if (!(R(RFX)&ZF)) {
STR_MOVE(p1->reg, len); STR_MOVE(p1->reg, len);
} }
} }
@ -170,7 +170,7 @@ static void cmpzs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
COMPARE(x1, x2); COMPARE(x1, x2);
if (!x1 && !x2) if (!x1 && !x2)
flg &= ~ZF; R(RFX) &= ~ZF;
STR_MOVE(p1->reg, len); STR_MOVE(p1->reg, len);
STR_MOVE(p2->reg, len); STR_MOVE(p2->reg, len);
@ -207,7 +207,7 @@ static void movs_impl(ctx_t *ctx, acc_t *p1, acc_t *p2, uint len)
ulong x = readmem(ctx, R(p2->reg), len); ulong x = readmem(ctx, R(p2->reg), len);
writemem(ctx, x, R(p1->reg), len); writemem(ctx, x, R(p1->reg), len);
flg = (x == 0 ? flg|ZF : flg&~ZF); R(RFX) = (x == 0 ? R(RFX)|ZF : R(RFX)&~ZF);
STR_MOVE(p1->reg, len); STR_MOVE(p1->reg, len);
STR_MOVE(p2->reg, len); STR_MOVE(p2->reg, len);

View File

@ -14,7 +14,7 @@ IMPL_END;
IMPL_START_0(into) IMPL_START_0(into)
{ {
if (flg & OF) if (R(RFX) & OF)
_except(ctx, E_OVF, "INTO instruction with FLG.OF=1"); _except(ctx, E_OVF, "INTO instruction with FLG.OF=1");
} }
IMPL_END; IMPL_END;
@ -25,7 +25,7 @@ IMPL_START_0(iret)
{ {
trace("\nReturning from exception #%ld\n\n", R(R11)); trace("\nReturning from exception #%ld\n\n", R(R11));
rip = R(R13); R(RIP) = R(R13);
rfs_current_idx = R(R12); rfs_current_idx = R(R12);
ctx->rf = rfs[R(R12)]; ctx->rf = rfs[R(R12)];
} }

View File

@ -58,6 +58,9 @@ struct ctx_t
// Instruction currently executing // Instruction currently executing
instr_t *cur_in; instr_t *cur_in;
// Starting address of instruction currently executing
ulong cur_pc;
// Memory and memory size // Memory and memory size
ushort *mp; ushort *mp;
ulong mz; ulong mz;
@ -65,14 +68,12 @@ struct ctx_t
// Read next instruction // Read next instruction
ushort (*get)(ctx_t *ctx); ushort (*get)(ctx_t *ctx);
// Step by step
int step;
// Devices list head // Devices list head
dev_t *dh; dev_t *dh;
// Instructions executed so far // Instructions executed
ulong ninstrs; ulong ninstrs; // totally
ulong ni_thisfr; // this frame
// Last COND field // Last COND field
uint cond; uint cond;

View File

@ -43,11 +43,11 @@ static void checkreg(ctx_t *ctx, uint reg, bool inv_is_ok)
return; return;
} }
if (ctx->r[reg].flags & (RES | CTL)) if (ctx->r[reg].flags & RES)
//_except(ctx, E_ACC, "Reserved REG: %u", reg); //_except(ctx, E_ACC, "Reserved REG: %u", reg);
if (ctx->r[reg].flags & SYS) if (ctx->r[reg].flags & SYS)
if (cr0 & UF) if (R(CR0) & UF)
_except(ctx, E_SYS, "User access to SYS REG: %u", reg); _except(ctx, E_SYS, "User access to SYS REG: %u", reg);
} }
@ -160,7 +160,7 @@ void decode(ctx_t *ctx)
ushort w1, w2; ushort w1, w2;
uchar f1 = 0, f2 = 0, f3 = 0; uchar f1 = 0, f2 = 0, f3 = 0;
rpc = rip; rpc = R(RIP);
// //
// Process the first word of the instruction // Process the first word of the instruction

View File

@ -91,7 +91,7 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
R(R10) = code; R(R10) = code;
R(R11) = effcode; R(R11) = effcode;
R(R12) = orig_frame; R(R12) = orig_frame;
R(R13) = rip; R(R13) = R(RIP);
idt_handling[effcode]++; idt_handling[effcode]++;

View File

@ -15,25 +15,25 @@ bool eval_cond(ctx_t *ctx, uint cond)
{ {
case CD_NONE: ok = 1; break; case CD_NONE: ok = 1; break;
case CD_C: ok = flg&CF; break; case CD_C: ok = rfx&CF; break;
case CD_O: ok = flg&OF; break; case CD_O: ok = rfx&OF; break;
case CD_Z: ok = flg&ZF; break; case CD_Z: ok = rfx&ZF; break;
case CD_S: ok = flg&SF; break; case CD_S: ok = rfx&SF; break;
case CD_P: ok = flg&PF; break; case CD_P: ok = rfx&PF; break;
case CD_A: ok = !(flg&CF || flg&ZF); break; case CD_A: ok = !(rfx&CF || rfx&ZF); break;
case CD_AE: ok = !(flg&CF); break; case CD_AE: ok = !(rfx&CF); break;
case CD_B: ok = flg&CF; break; case CD_B: ok = rfx&CF; break;
case CD_BE: ok = flg&CF || flg&ZF; break; case CD_BE: ok = rfx&CF || rfx&ZF; break;
case CD_G: ok = !(flg&ZF) && (!(flg&SF) == !(flg&OF)); break; case CD_G: ok = !(rfx&ZF) && (!(rfx&SF) == !(rfx&OF)); break;
case CD_GE: ok = !(flg&SF) == !(flg&OF); break; case CD_GE: ok = !(rfx&SF) == !(rfx&OF); break;
case CD_L: ok = !(flg&SF) != !(flg&OF); break; case CD_L: ok = !(rfx&SF) != !(rfx&OF); break;
case CD_LE: ok = flg&ZF || (!(flg&SF) != !(flg&OF)); break; case CD_LE: ok = rfx&ZF || (!(rfx&SF) != !(rfx&OF)); break;
case CD_CXZ: ok = !rcx; break; case CD_CXZ: ok = !R(RCX); break;
default: default:
_except(ctx, E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond)); _except(ctx, E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond));
@ -80,7 +80,7 @@ do_rep:
#define OUTPUT(p, r) { \ #define OUTPUT(p, r) { \
if (p->type == A_REG) \ if (p->type == A_REG) \
R(p->reg) = r1; \ R(p->reg) = r; \
else if (p1->type == A_IMM64) \ else if (p1->type == A_IMM64) \
_except(ctx, E_ACC, "Trying to output to an IMM64"); \ _except(ctx, E_ACC, "Trying to output to an IMM64"); \
else { \ else { \
@ -102,10 +102,10 @@ do_rep:
if (!eval_cond(ctx, ctx->cond)) if (!eval_cond(ctx, ctx->cond))
return; return;
if (rcx > 0) if (R(RCX) > 0)
rcx--; R(RCX)--;
if (rcx == 0) if (R(RCX) == 0)
return; return;
// Should we really count REP's in instruction count? // Should we really count REP's in instruction count?

View File

@ -13,19 +13,17 @@ static ushort *fwprog;
ushort bget(ctx_t *ctx) ushort bget(ctx_t *ctx)
{ {
ulong addr = rip + cr1; ulong addr = R(RIP) + R(CR1);
if (addr2real(addr) >= ctx->mz) { if (addr2real(addr) >= ctx->mz) {
_except(ctx, E_ACC, "Executing out of memory: " _except(ctx, E_ACC, "Executing out of memory: "
"rip=0x%lX cr1=0x%lX", "rip=0x%lX cr1=0x%lX",
rip, cr1); R(RIP), R(RIP));
} }
ushort c = ctx->mp[addr2real(addr)]; ushort c = ctx->mp[addr2real(addr)];
//log("bget 0x%lX: 0x%lX\n", addr, c); R(RIP) += 2;
rip += 2;
return c; return c;
} }
@ -67,9 +65,6 @@ void main_loop(void)
decode(&main_ctx); decode(&main_ctx);
console_update(&main_ctx); console_update(&main_ctx);
if (main_ctx.step)
getchar();
} }
die(0); die(0);

View File

@ -129,7 +129,7 @@ static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
} }
#define GETREAL() \ #define GETREAL() \
ulong real = addr2real(addr + cr2) ulong real = addr2real(addr + R(CR2))
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//

View File

@ -5,97 +5,50 @@
reg_t arch_r[] = reg_t arch_r[] =
{ {
{ "inv", RES }, { "flg", GPR }, { "rip", GPR }, { "rpc", GPR }, { "inv", RES }, { "fc1", RES }, { "cr0", SYS }, { "cr1", SYS },
{ "px0", RES }, { "px1", RES }, { "fc1", RES }, { "fc2", RES }, { "cr2", SYS }, { "cr3", SYS }, { "cr4", SYS }, { "trp", GPR },
{ "sa0", SYS }, { "sa1", SYS }, { "sa2", SYS }, { "sa3", SYS },
{ "cr0", SYS }, { "cr1", SYS }, { "cr2", SYS }, { "cr3", SYS },
{ "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR }, { "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR },
{ "rsi", GPR }, { "rdi", GPR }, { "rbp", GPR }, { "rsp", GPR }, { "rsi", GPR }, { "rdi", GPR }, { "rbp", GPR }, { "rsp", GPR },
{ "rx8", GPR }, { "rx9", GPR }, { "r10", GPR }, { "r11", GPR }, { "rfx", GPR }, { "rip", GPR }, { "r10", GPR }, { "r11", GPR },
{ "r12", GPR }, { "r13", GPR }, { "r14", GPR }, { "r15", GPR }, { "r12", GPR }, { "r13", GPR }, { "r14", GPR }, { "r15", GPR },
{ "ax0", GPR }, { "ax1", GPR }, { "ax2", GPR }, { "ax3", GPR }, { "ax0", GPR }, { "ax1", GPR }, { "ax2", GPR }, { "ax3", GPR },
{ "ax4", GPR }, { "ax5", GPR }, { "ax6", GPR }, { "ax7", GPR }, { "ax4", GPR }, { "ax5", GPR }, { "ax6", GPR }, { "ax7", GPR },
{ "ax8", GPR }, { "ax9", GPR }, { "a10", GPR }, { "a11", GPR },
{ "a12", GPR }, { "a13", GPR }, { "a14", GPR }, { "a15", GPR },
{ "nx0", GPR }, { "nx1", GPR }, { "nx2", GPR }, { "nx3", GPR }, { "nx0", GPR }, { "nx1", GPR }, { "nx2", GPR }, { "nx3", GPR },
{ "nx4", GPR }, { "nx5", GPR }, { "nx6", GPR }, { "nx7", GPR }, { "nx4", GPR }, { "nx5", GPR }, { "nx6", GPR }, { "nx7", GPR },
{ "nx8", GPR }, { "nx9", GPR }, { "n10", GPR }, { "n11", GPR },
{ "n12", GPR }, { "n13", GPR }, { "n14", GPR }, { "n15", GPR },
// { "dr0", SYS }, { "dr1", SYS }, { "dr2", SYS }, { "dr3", SYS },
// { "sa4", SYS }, { "sa5", SYS }, { "sa6", SYS }, { "sa7", SYS },
// { "dr4", SYS }, { "dr5", SYS }, { "dr6", SYS }, { "dr7", SYS },
// { "cr4", CTL }, { "cr5", CTL }, { "cr6", CTL }, { "cr7", CTL },
/*
{ "r16", GPR }, { "r17", GPR }, { "r18", GPR }, { "r19", GPR },
{ "r20", GPR }, { "r21", GPR }, { "r22", GPR }, { "r23", GPR },
{ "r24", GPR }, { "r25", GPR }, { "r26", GPR }, { "r27", GPR },
{ "r28", GPR }, { "r29", GPR }, { "r30", GPR }, { "r31", GPR },
{ "a16", GPR }, { "a17", GPR }, { "a18", GPR }, { "a19", GPR },
{ "a20", GPR }, { "a21", GPR }, { "a22", GPR }, { "a23", GPR },
{ "a24", GPR }, { "a25", GPR }, { "a26", GPR }, { "a27", GPR },
{ "a28", GPR }, { "a29", GPR }, { "a30", GPR }, { "a31", GPR },
{ "n16", GPR }, { "n17", GPR }, { "n18", GPR }, { "n19", GPR },
{ "n20", GPR }, { "n21", GPR }, { "n22", GPR }, { "n23", GPR },
{ "n24", GPR }, { "n25", GPR }, { "n26", GPR }, { "n27", GPR },
{ "n28", GPR }, { "n29", GPR }, { "n30", GPR }, { "n31", GPR },
*/
}; };
static_assert(NREGS <= 256, "");
static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, ""); static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, "");
#define DUMPREGS(down, up) \
for (i = down; i <= up; i++) { \
if (i % 4 == 0) \
trace("\n"); \
r = &ctx->r[i]; \
trace("%s=0x%-16lX ", r->name, R(i)); \
} \
void dumpregs(ctx_t *ctx) void dumpregs(ctx_t *ctx)
{ {
int i; trace("Current RFRAME index: #%lu", rfs_current_idx);
reg_t *r;
trace("Current RFRAME index: #%lu\n", rfs_current_idx); trace("\n\nEnviron:");
trace("\nrpc=0x%-16lX rip=0x%-16lX rfx=0x%-16lX", rpc, R(RIP), R(RFX));
trace("\nrsp=0x%-16lX rbp=0x%-16lX trp=0x%-16lX", R(RSP), R(RBP), R(TRP));
DUMPREGS(RAX, R15); trace("\n\nControl:");
trace("\ncr0=0x%-16lX cr1=0x%-16lX cr2=0x%-16lX", R(CR0), R(CR1), R(CR2));
trace("\nfc0=0d%-16lu fc1=0d%-16lu fc2=0d%-16lu", fc0, fc1, fc2);
trace("\n\nArgument:");
trace("\nax0=0x%-16lX ax1=0x%-16lX ax2=0x%-16lX", R(AX0), R(AX1), R(AX2));
trace("\nax3=0x%-16lX ax4=0x%-16lX ax5=0x%-16lX", R(AX3), R(AX4), R(AX5));
trace("\n\nVolatile:");
trace("\nrax=0x%-16lX rcx=0x%-16lX rdx=0x%-16lX", R(RAX), R(RCX), R(RDX));
trace("\nr10=0x%-16lX r11=0x%-16lX r12=0x%-16lX", R(R10), R(R11), R(R12));
trace("\nr13=0x%-16lX r14=0x%-16lX r15=0x%-16lX", R(R13), R(R14), R(R15));
trace("\n\nPersistent:");
trace("\nrbx=0x%-16lX rdi=0x%-16lX rsi=0x%-16lX", R(RBX), R(RDI), R(RSI));
trace("\nnx0=0x%-16lX nx1=0x%-16lX nx2=0x%-16lX", R(NX0), R(NX1), R(NX2));
trace("\nnx3=0x%-16lX nx4=0x%-16lX nx5=0x%-16lX", R(NX3), R(NX4), R(NX5));
trace("\n"); trace("\n");
DUMPREGS(AX0, A15);
trace("\n"); assert(R(INV) == 0);
DUMPREGS(NX0, N15);
trace("\n");
DUMPREGS(SA0, SA3);
DUMPREGS(CR0, CR3);
trace("\n\nrip=0x%-16lX rpc=0x%-16lX rsp=0x%-16lX rbp=0x%-16lX",
rip, rpc, rsp, rbp);
trace("\nfc0=0d%-16lu fc1=0d%-16lu fc2=0d%-16lu flg=0x%-16lX\n",
fc0, fc1, fc2, flg);
/*
trace("\nCF=%x OF=%x\n"
"ZF=%x SF=%x\n"
"PF=%x DF=%x\n"
"IF=%x UF=%x\n",
!!(flg&CF), !!(flg&OF),
!!(flg&ZF), !!(flg&SF),
!!(flg&PF), !!(flg&DF),
!!(cr0&IF), !!(cr0&UF));
*/
assert(inv == 0);
} }

View File

@ -4,24 +4,22 @@
// Register types // Register types
enum enum
{ {
GPR = 1 << 0, // General GPR = 0, // Non-reserved
CTL = 1 << 1, // Control RES = 1 << 0, // Reserved for insternal use
SEG = 1 << 2, // Segment SYS = 1 << 1, // Reserved for supervisor mode
RES = 1 << 8, // Reserved for insternal use
SYS = 1 << 9, // Reserved for supervisor mode
}; };
// FLG register // FLG register
enum enum
{ {
CF = 1 << 0, // Carry flag ZF = 1 << 0, // Zero flag
OF = 1 << 1, // Overflow flag SF = 1 << 1, // Sign flag
ZF = 1 << 2, // Zero flag CF = 1 << 4, // Carry flag
SF = 1 << 3, // Sign flag OF = 1 << 5, // Overflow flag
PF = 1 << 4, // Parity flag PF = 1 << 8, // Parity flag
DF = 1 << 5, // Direction flag DF = 1 << 9, // Direction flag
}; };
// CR0 register // CR0 register
@ -39,53 +37,25 @@ struct reg_t
enum enum
{ {
INV, FLG, RIP, RPC, PX0, PX1, FC1, FC2, INV, FC1, CR0, CR1, CR2, CR3, CR4, TRP,
SA0, SA1, SA2, SA3, // SA4, SA5, SA6, SA7,
CR0, CR1, CR2, CR3, // CR4, CR5, CR6, CR7,
RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP,
RX8, RX9, R10, R11, R12, R13, R14, R15, RFX, RIP, R10, R11, R12, R13, R14, R15,
AX0, AX1, AX2, AX3, AX4, AX5, AX6, AX7, AX0, AX1, AX2, AX3, AX4, AX5, AX6, AX7,
AX8, AX9, A10, A11, A12, A13, A14, A15,
NX0, NX1, NX2, NX3, NX4, NX5, NX6, NX7, NX0, NX1, NX2, NX3, NX4, NX5, NX6, NX7,
NX8, NX9, N10, N11, N12, N13, N14, N15,
// DR0, DR1, DR2, DR3, DR4, DR5, DR6, DR7,
// R16, R17, R18, R19, R20, R21, R22, R23,
// R24, R25, R26, R27, R28, R29, R30, R31,
// A16, A17, A18, A19, A20, A21, A22, A23,
// A24, A25, A26, A27, A28, A29, A30, A31,
// N16, N17, N18, N19, N20, N21, N22, N23,
// N24, N25, N26, N27, N28, N29, N30, N31,
NREGS NREGS
}; };
#define fc0 ctx->ninstrs #define fc0 ctx->ninstrs
#define fc2 ctx->ni_thisfr
#define rpc ctx->cur_pc
#define inv R(INV)
#define rip R(RIP)
#define rpc R(RPC)
#define flg R(FLG)
#define fc1 R(FC1) #define fc1 R(FC1)
#define fc2 R(FC2) #define rfx R(RFX)
#define cr0 R(CR0)
#define cr1 R(CR1)
#define cr2 R(CR2)
#define rax R(RAX) #define rax R(RAX)
#define rbx R(RBX)
#define rcx R(RCX)
#define rdx R(RDX) #define rdx R(RDX)
#define rsi R(RSI)
#define rdi R(RDI)
#define rbp R(RBP)
#define rsp R(RSP)
#define ax0 R(AX0) #define ax0 R(AX0)
#define ax1 R(AX1) #define ax1 R(AX1)
#define ax2 R(AX2)
#define ax3 R(AX3)