diff --git a/as/k-as.py b/as/k-as.py index 8612a48..8c40abb 100755 --- a/as/k-as.py +++ b/as/k-as.py @@ -437,6 +437,14 @@ pref2len = { "q" : 8, } +i_aliases = { + "j_1" : "jmp_1", + "m_2" : "mov_2", + "b_3" : "bch_3", + "inc_2" : "add_2", + "dec_2" : "sub_2", +} + def parse_instr(line): if line == None or len(line) == 0: return 0 @@ -480,22 +488,20 @@ def parse_instr(line): if params == None or len(params) == 0: if b2 == 0: - instrs.write("{}".format(instr_name)) + instrs.write("{}_0".format(instr_name)) else: size += 1 - instrs.write("%%suff {} %%imm8 {}".format(instr_name, b2)) + instrs.write("%%suff {}_0 %%imm8 {}".format(instr_name, b2)) return size tok = params.split(',') - # 'call' special case... temporary - if instr_name == 'call': - if len(tok) == 2: - instr_name = 'xcall2' - elif len(tok) == 3: - instr_name = 'xcall3' + instr_name += "_{}".format(len(tok)) + + if instr_name in i_aliases: + instr_name = i_aliases[instr_name] # # Parse operands diff --git a/ka/crt/fmt/doprnt.k b/ka/crt/fmt/doprnt.k index 95ea965..d1467e1 100644 --- a/ka/crt/fmt/doprnt.k +++ b/ka/crt/fmt/doprnt.k @@ -9,12 +9,8 @@ doprnt: push rbp mov rbp, rsp - push r12 - push r13 - push r14 - push r15 - push r16 - push r17 + push r12, r13, r14 + push r15, r16, r17 mov r12, ax2 ; fmt mov r14, ax3 ; va_list @@ -145,13 +141,9 @@ doprnt: .epilogue: mov rax, r16 - - pop r17 - pop r16 - pop r15 - pop r14 - pop r13 - pop r12 + + pop r17, r16, r15 + pop r14, r13, r12 leave ret diff --git a/ka/crt/fmt/ltostr.k b/ka/crt/fmt/ltostr.k index 8517144..f1b9fdb 100644 --- a/ka/crt/fmt/ltostr.k +++ b/ka/crt/fmt/ltostr.k @@ -53,9 +53,10 @@ ltostr: .next: mov b[ax0], rdx + inc ax0, 1 - div ax1, ax1, ax2 + div ax1, ax2 jmp .conv ; add minus flag, null-terminate and reverse diff --git a/ka/crt/fmt/strtol.k b/ka/crt/fmt/strtol.k index 487bb8d..66f09dd 100644 --- a/ka/crt/fmt/strtol.k +++ b/ka/crt/fmt/strtol.k @@ -137,7 +137,7 @@ strtoq: ; too large for base? b.ae rcx, ax1, .done - mul rax, rax, ax1 + mul rax, ax1 inc rax, rcx jmp .main_loop diff --git a/ka/crt/lib/time.k b/ka/crt/lib/time.k index 9c6ac2c..78b7bba 100644 --- a/ka/crt/lib/time.k +++ b/ka/crt/lib/time.k @@ -54,12 +54,12 @@ GetTimeUTC: ; minutes div rcx, ax0, 60 - rem rcx, rcx, 60 + rem rcx, 60 mov b[rdx+1], rcx ; hours div rcx, ax0, 3600 - rem rcx, rcx, 24 + rem rcx, 24 mov b[rdx+2], rcx ; month days diff --git a/ka/sys/dumprf.k b/ka/sys/dumprf.k index af68f66..c9d8e1b 100644 --- a/ka/sys/dumprf.k +++ b/ka/sys/dumprf.k @@ -5,8 +5,9 @@ dumprf: push rbp mov rbp, rsp - push r12 + push r12, r13 mov r12, ax0 + mov r13, rsp call RFS.LoadReg, r12, $cr2 push rax @@ -113,7 +114,8 @@ dumprf: call printf, .dmp6 - pop r12 + mov rsp, r13 + pop r13, r12 leave ret diff --git a/ka/sys/intr/common.k b/ka/sys/intr/common.k index 252e355..c8304bf 100644 --- a/ka/sys/intr/common.k +++ b/ka/sys/intr/common.k @@ -1,31 +1,6 @@ ; The OS/K Team licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. -TrapHandlers.prolog: - mov rbp, zero - - ; rax = caller's cr2 - call RFS.LoadReg, r14, $cr2 - - ; we don't preserve the r12 we got - mov r12, rax - mov rdx, zero - - jmp rcx - -TrapHandlers.epilog: - ; TRAP return values: RAX-RDX - - mov ax2, rax - call RFS.StoreReg, r14, $rax - - mov ax2, rdx - call RFS.StoreReg, r14, $rdx - - call IDT.DoneHandling, r13 - - iret - ScreenOfDeath: push r12 mov r12, ax0 @@ -51,8 +26,7 @@ ScreenOfDeath: push .scr2_usr .do_print: - push r14 - push r12 + push r14, r12 call printf, .scr2 inc rsp, 24 diff --git a/ka/sys/intr/trap0.k b/ka/sys/intr/trap0.k index 1b34a41..3cd2cad 100644 --- a/ka/sys/intr/trap0.k +++ b/ka/sys/intr/trap0.k @@ -1,6 +1,34 @@ ; The OS/K Team licenses this file to you under the MIT license. ; See the LICENSE file in the project root for more information. +TrapHandlers.prolog: + mov rbp, zero + + ; rax = caller's cr2 + call RFS.LoadReg, r14, $cr2 + + ; we don't preserve the r12 we got + mov r12, rax + mov rdx, zero + + jmp rcx + +TrapHandlers.epilog: + ; TRAP return values: RAX-RDX + + mov ax2, rax + call RFS.StoreReg, r14, $rax + + mov ax2, rdx + call RFS.StoreReg, r14, $rdx + + call IDT.DoneHandling, r13 + + iret + +; +; TRAP #0 handler +; DefaultTrapHandler: .init: diff --git a/ka/usr/cmd/dir.k b/ka/usr/cmd/dir.k index 05dcae6..ee6feee 100644 --- a/ka/usr/cmd/dir.k +++ b/ka/usr/cmd/dir.k @@ -7,10 +7,8 @@ builtins.dir: push rbp mov rbp, rsp - push r12 - push r13 - push r14 - push r15 + push r12, r13 + push r14, r15 mov r12, zero # no. of files found mov r13, zero # no. of directories found @@ -110,24 +108,19 @@ builtins.dir: .end: shr rax, r14, 10 shr rdx, rax, 10 - and rax, rax, 1023 - and r14, r14, 1023 + and rax, 1023 + and r14, 1023 - push r14 - push rax - push rdx + push r14, rax, rdx call printf, .endstr0 inc rsp, 24 - push r13 - push r12 + push r13, r12 call printf, .endstr1 inc rsp, 16 - pop r15 - pop r14 - pop r13 - pop r12 + pop r15, r14 + pop r13, r12 leave ret diff --git a/ka/usr/cmd/main.k b/ka/usr/cmd/main.k index 02463a9..3ca1335 100644 --- a/ka/usr/cmd/main.k +++ b/ka/usr/cmd/main.k @@ -211,12 +211,10 @@ main: .handle_DATE: call GetTimeUTC - push b[rax+3] mov rcx, b[rax+4] inc rcx, 1 - push rcx - push w[rax+6] + push b[rax+3], rcx, w[rax+6] call printf, .datefmt inc rsp, 40 @@ -322,9 +320,7 @@ main: .handle_TIME: call GetTimeUTC - push b[rax] - push b[rax+1] - push b[rax+2] + push b[rax], b[rax+1], b[rax+2] call printf, .timefmt inc rsp, 24 @@ -383,8 +379,7 @@ main: .cnf_errmsg = ": command not found\n" .file_not_found: - push q[argv1pos] - push argv0 + push q[argv1pos], argv0 call printf, .fnf_errmsg inc rsp, 16 @@ -393,8 +388,7 @@ main: .fnf_errmsg = "%s: %s: file not found\n" .empty_file: - push q[argv1pos] - push argv0 + push q[argv1pos], argv0 call printf, .ef_errmsg inc rsp, 16 @@ -403,8 +397,7 @@ main: .ef_errmsg = "%s: %s: file was empty\n" .couldnt_open: - push q[argv1pos] - push argv0 + push q[argv1pos], argv0 call printf, .cno_errmsg inc rsp, 16 @@ -413,8 +406,7 @@ main: .cno_errmsg = "%s: %s: an error occured while opening file\n" .couldnt_remove: - push q[argv1pos] - push argv0 + push q[argv1pos], argv0 call printf, .cne_errmsg inc rsp, 16 @@ -423,8 +415,7 @@ main: .cne_errmsg = "%s: %s: an error occured while removing file\n" .couldnt_read: - push q[argv1pos] - push argv0 + push q[argv1pos], argv0 call printf, .cnr_errmsg inc rsp, 16 diff --git a/vm/in/ALU b/vm/in/ALU index a095baa..f284dfd 100644 --- a/vm/in/ALU +++ b/vm/in/ALU @@ -12,6 +12,7 @@ # # Preserves all flags # +or 2 or 3 # @@ -21,6 +22,7 @@ or 3 # # Preserves all flags # +and 2 and 3 # @@ -30,6 +32,7 @@ and 3 # # Preserves all flags # +xor 2 xor 3 # @@ -40,7 +43,9 @@ xor 3 # # Preserves all flags # +shl 2 shl 3 +shr 2 shr 3 # @@ -50,6 +55,7 @@ shr 3 # # Preserves all flags # +sar 2 sar 3 #---------------------------------------------------------------------------# @@ -76,7 +82,7 @@ cmp 2 # Sets OF is signed integer overflow occur, clears it otherwise # Sets ZF and SF according to the result # -inc 2 +add 2 add 3 addf 3 @@ -89,7 +95,7 @@ addf 3 # Sets OF is signed integer overflow occur, clears it otherwise # Sets ZF and SF according to the result # -dec 2 +sub 2 sub 3 subf 3 @@ -103,7 +109,9 @@ subf 3 # Sets OF is signed integer overflow occur, clears it otherwise # Sets ZF and SF according to the result # +adcx 2 adcx 3 +sbbx 2 sbbx 3 # @@ -114,6 +122,7 @@ sbbx 3 # Preserves ZF and SF # Sets CF and OF if HI($src1 * $src2) > 0, clears them otherwise # +mul 2 mul 3 mulf 3 @@ -142,6 +151,7 @@ imulhi 3 # # Preserves all flags # +div 2 div 3 # @@ -151,6 +161,7 @@ div 3 # # Preserves all flags # +idiv 2 idiv 3 # @@ -160,5 +171,6 @@ idiv 3 # # Preserves all flags # +rem 2 rem 3 diff --git a/vm/in/MEM b/vm/in/MEM index 05779f8..481cefc 100644 --- a/vm/in/MEM +++ b/vm/in/MEM @@ -23,7 +23,7 @@ jmp 1 loop 1 # -# Conditional absolute jumps (B) +# Conditional absolute jumps (branches) (BCH) # # COMPARE(SignExtend($1), $2) # @@ -38,7 +38,7 @@ loop 1 # # Suffixing B with the REP suffix results in undefined behavior # -b 3 +bch 3 #---------------------------------------------------------------------------# @@ -52,8 +52,8 @@ b 3 # JMP(RIP) # call 1 -xcall2 2 -xcall3 3 +call 2 +call 3 # # Return to caller (RET) @@ -69,6 +69,7 @@ ret # RBP = RSP # RSP = RSP - $1 # +enter enter 1 # @@ -86,6 +87,8 @@ leave # *RSP = $1 # push 1 +push 2 +push 3 # # POP value from stack @@ -94,6 +97,8 @@ push 1 # RSP = RSP + 8 # pop 1 +pop 2 +pop 3 #---------------------------------------------------------------------------# # Movement instructions # diff --git a/vm/in/MISC b/vm/in/MISC index 7b0533c..443d14f 100644 --- a/vm/in/MISC +++ b/vm/in/MISC @@ -43,7 +43,7 @@ into # # Get timestamp in µseconds # -utime 2 +utime 1 # # $1 = seconds since start of month diff --git a/vm/in/alu.c b/vm/in/alu.c index 35adff5..c697e63 100644 --- a/vm/in/alu.c +++ b/vm/in/alu.c @@ -8,30 +8,46 @@ //----------------------------------------------------------------------------// -IMPL_START(or) { SRCP(p2); SRCP(p3); *r1 = p2->val | p3->val; return 1; } -IMPL_START(and) { SRCP(p2); SRCP(p3); *r1 = p2->val & p3->val; return 1; } -IMPL_START(xor) { SRCP(p2); SRCP(p3); *r1 = p2->val ^ p3->val; return 1; } +IMPL_START(or, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val | p2->val; return 1; } +IMPL_START(and, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val & p2->val; return 1; } +IMPL_START(xor, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val ^ p2->val; return 1; } + +IMPL_START(or, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val | p3->val; return 1; } +IMPL_START(and, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val & p3->val; return 1; } +IMPL_START(xor, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val ^ p3->val; return 1; } //----------------------------------------------------------------------------// -IMPL_START(shl) { SRCP(p2); SRCP(p3); *r1 = p2->val << p3->val; return 1; } -IMPL_START(shr) { SRCP(p2); SRCP(p3); *r1 = p2->val >> p3->val; return 1; } -IMPL_START(sar) { SRCP(p2); SRCP(p3); *r1 = (ulong)((long)p2->val >> (long)p3->val); return 1; } +IMPL_START(shl, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val << p2->val; return 1; } +IMPL_START(shr, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val >> p2->val; return 1; } +IMPL_START(sar, 2) { SRCP(p1); SRCP(p2); *r1 = (ulong)((long)p1->val >> (long)p2->val); return 1; } + +IMPL_START(shl, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val << p3->val; return 1; } +IMPL_START(shr, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val >> p3->val; return 1; } +IMPL_START(sar, 3) { SRCP(p2); SRCP(p3); *r1 = (ulong)((long)p2->val >> (long)p3->val); return 1; } //----------------------------------------------------------------------------// -IMPL_START(inc) { SRCP(p1); SRCP(p2); *r1 = p1->val + p2->val; return 1; } -IMPL_START(add) { SRCP(p2); SRCP(p3); *r1 = p2->val + p3->val; return 1; } -IMPL_START(addf) { SRCP(p2); SRCP(p3); COMPARE_ADD(p2->val, p3->val); *r1 = p2->val + p3->val; return 1; } +IMPL_START(add, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val + p2->val; return 1; } +IMPL_START(add, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val + p3->val; return 1; } +IMPL_START(addf, 3) { SRCP(p2); SRCP(p3); COMPARE_ADD(p2->val, p3->val); *r1 = p2->val + p3->val; return 1; } -IMPL_START(dec) { SRCP(p1); SRCP(p2); *r1 = p1->val - p2->val; return 1; } -IMPL_START(sub) { SRCP(p2); SRCP(p3); *r1 = p2->val - p3->val; return 1; } -IMPL_START(subf) { SRCP(p2); SRCP(p3); COMPARE_SUB(p2->val, p3->val); *r1 = p2->val - p3->val; return 1; } +IMPL_START(sub, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val - p2->val; return 1; } +IMPL_START(sub, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val - p3->val; return 1; } +IMPL_START(subf, 3) { SRCP(p2); SRCP(p3); COMPARE_SUB(p2->val, p3->val); *r1 = p2->val - p3->val; return 1; } -IMPL_START(adcx) -{ - SRCP(p2); - SRCP(p3); +IMPL_START(adcx, 2) { + SRCP(p1); SRCP(p2); + + p2->val += !!(R(RFX)&CF); + COMPARE_ADD(p1->val, p2->val); + *r1 = p1->val + p2->val; + + return 1; +} + +IMPL_START(adcx, 3) { + SRCP(p2); SRCP(p3); p3->val += !!(R(RFX)&CF); COMPARE_ADD(p2->val, p3->val); @@ -40,10 +56,18 @@ IMPL_START(adcx) return 1; } -IMPL_START(sbbx) -{ - SRCP(p2); - SRCP(p3); +IMPL_START(sbbx, 2) { + SRCP(p1); SRCP(p2); + + p2->val += !!(R(RFX)&CF); + COMPARE_SUB(p1->val, p2->val); + *r1 = p1->val - p2->val; + + return 1; +} + +IMPL_START(sbbx, 3) { + SRCP(p2); SRCP(p3); p3->val += !!(R(RFX)&CF); COMPARE_SUB(p2->val, p3->val); @@ -54,29 +78,43 @@ IMPL_START(sbbx) //----------------------------------------------------------------------------// -IMPL_START(mul) { SRCP(p2); SRCP(p3); *r1 = p2->val * p3->val; return 1; } -IMPL_START(rem) { SRCP(p2); SRCP(p3); *r1 = p2->val % p3->val; return 1; } +IMPL_START(mul, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val * p2->val; return 1; } +IMPL_START(mul, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val * p3->val; return 1; } -IMPL_START(div) -{ - SRCP(p2); - SRCP(p3); +IMPL_START(rem, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val % p2->val; return 1; } +IMPL_START(rem, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val % p3->val; return 1; } - if (!p3->val) - _except(E_DIV, "DIV by 0"); +IMPL_START(div, 2) { + SRCP(p1); SRCP(p2); + + if (!p2->val) _except(E_DIV, "DIV by 0"); + *r1 = p1->val / p2->val; + + return 1; +} + +IMPL_START(div, 3) { + SRCP(p2); SRCP(p3); + + if (!p3->val) _except(E_DIV, "DIV by 0"); *r1 = p2->val / p3->val; return 1; } -IMPL_START(idiv) -{ - SRCP(p2); - SRCP(p3); +IMPL_START(idiv, 2) { + SRCP(p1); SRCP(p2); - if (!p3->val) - _except(E_DIV, "IDIV by 0"); + if (!p3->val) _except(E_DIV, "IDIV by 0"); + *r1 = (ulong)((long)p1->val/(long)p2->val); + return 1; +} + +IMPL_START(idiv, 3) { + SRCP(p2); SRCP(p3); + + if (!p3->val) _except(E_DIV, "IDIV by 0"); *r1 = (ulong)((long)p2->val/(long)p3->val); return 1; @@ -92,7 +130,7 @@ static void __unsigned_multiply128(ulong u, ulong v, ulong *hi, ulong *lo) *lo = r; } -IMPL_START(mulhi) +IMPL_START(mulhi, 3) { SRCP(p2); SRCP(p3); @@ -101,7 +139,7 @@ IMPL_START(mulhi) return 2; } -IMPL_START(mulf) +IMPL_START(mulf, 3) { SRCP(p2); SRCP(p3); @@ -123,7 +161,7 @@ static void __signed_multiply128(ulong u, ulong v, ulong *hi, ulong *lo) *lo = r; } -IMPL_START(imulhi) +IMPL_START(imulhi, 3) { SRCP(p2); SRCP(p3); diff --git a/vm/in/arch_i.py b/vm/in/arch_i.py index 232a40c..fa6f668 100644 --- a/vm/in/arch_i.py +++ b/vm/in/arch_i.py @@ -47,15 +47,15 @@ def parse_2(fp): assert(len(tok) == 2) n = tok[1] - ls.write("{}{}\n".format(deprecated, tok[0])) + ls.write("{}{}_{}\n".format(deprecated, tok[0], n)) hd.write("#ifdef _NEED_ARCH_I\n") - hd.write('{{ "{}{}", {}, i_{} }},\n'\ - .format(deprecated, tok[0], n, tok[0])) + hd.write('{{ "{}{}", {}, i_{}_{} }},\n'\ + .format(deprecated, tok[0], n, tok[0], n)) hd.write("#else\n") - hd.write("#define I_{} {}\n".format(tok[0].upper(), count)) - hd.write("extern bool i_{}(acc_t *, acc_t *, acc_t *, ulong *, ulong *, ulong *);\n" - .format(tok[0])) + hd.write("#define I_{}_{} {}\n".format(tok[0].upper(), n, count)) + hd.write("extern bool i_{}_{}(acc_t *, acc_t *, acc_t *, ulong *, ulong *, ulong *);\n" + .format(tok[0], n)) hd.write("#endif\n\n") count = count + 1 diff --git a/vm/in/instrs.h b/vm/in/instrs.h index d36e1f9..c1c925f 100644 --- a/vm/in/instrs.h +++ b/vm/in/instrs.h @@ -5,8 +5,8 @@ //----------------------------------------------------------------------------// -#define IMPL_START(name) \ -uint i_##name(acc_t *p1, acc_t *p2, acc_t *p3, \ +#define IMPL_START(name, n) \ +uint i_##name##_##n(acc_t *p1, acc_t *p2, acc_t *p3, \ ulong *r1, ulong *r2, ulong *r3) \ #define XSRCP(v, p, x) \ diff --git a/vm/in/mem.c b/vm/in/mem.c index db5d936..d9ebcc6 100644 --- a/vm/in/mem.c +++ b/vm/in/mem.c @@ -5,9 +5,9 @@ //----------------------------------------------------------------------------// -IMPL_START(jmp) { R(RIP) = p1->val; return 0; } +IMPL_START(jmp, 1) { R(RIP) = p1->val; return 0; } -IMPL_START(loop) { +IMPL_START(loop, 1) { if (R(RCX) > 0) { R(RCX)--; R(RIP) = p1->val; @@ -15,7 +15,7 @@ IMPL_START(loop) { return 0; } -IMPL_START(b) +IMPL_START(bch, 3) { SRCP(p1); SRCP(p2); @@ -28,7 +28,7 @@ IMPL_START(b) return 0; } -IMPL_START(cmp) +IMPL_START(cmp, 2) { SRCP(p1); @@ -39,15 +39,15 @@ IMPL_START(cmp) //----------------------------------------------------------------------------// -IMPL_START(lea) { *r1 = p2->addr; return 1; } -IMPL_START(mov) { XSRCP(*r1, p2, sx); return 1; } -IMPL_START(movzx) { XSRCP(*r1, p2, zx); return 1; } +IMPL_START(lea, 2) { *r1 = p2->addr; return 1; } +IMPL_START(mov, 2) { XSRCP(*r1, p2, sx); return 1; } +IMPL_START(movzx, 2) { XSRCP(*r1, p2, zx); return 1; } -IMPL_START(movsxb) { SRCP(p2); *r1 = (ulong)(long)(char)p2->val; return 1; } -IMPL_START(movsxw) { SRCP(p2); *r1 = (ulong)(long)(short)p2->val; return 1; } -IMPL_START(movsxd) { SRCP(p2); *r1 = (ulong)(long)(int)p2->val; return 1; } +IMPL_START(movsxb, 2) { SRCP(p2); *r1 = (ulong)(long)(char)p2->val; return 1; } +IMPL_START(movsxw, 2) { SRCP(p2); *r1 = (ulong)(long)(short)p2->val; return 1; } +IMPL_START(movsxd, 2) { SRCP(p2); *r1 = (ulong)(long)(int)p2->val; return 1; } -IMPL_START(xchg) +IMPL_START(xchg, 2) { SRCP(p1); SRCP(p2); @@ -60,11 +60,7 @@ IMPL_START(xchg) //----------------------------------------------------------------------------// -// -// Stack manipulation instructions -// - -IMPL_START(push) +IMPL_START(push, 1) { XSRCP(p1->val, p1, zx); @@ -74,7 +70,35 @@ IMPL_START(push) return 0; } -IMPL_START(pop) +IMPL_START(push, 2) +{ + XSRCP(p1->val, p1, zx); + XSRCP(p2->val, p2, zx); + + R(RSP) -= 16; + writemem(p1->val, R(RSP) + 8, 8); + writemem(p2->val, R(RSP) + 0, 8); + + return 0; +} + +IMPL_START(push, 3) +{ + XSRCP(p1->val, p1, zx); + XSRCP(p2->val, p2, zx); + XSRCP(p3->val, p3, zx); + + R(RSP) -= 24; + writemem(p1->val, R(RSP) + 16, 8); + writemem(p2->val, R(RSP) + 8, 8); + writemem(p3->val, R(RSP) + 0, 8); + + return 0; +} + +//----------------------------------------------------------------------------// + +IMPL_START(pop, 1) { *r1 = readmemzx(R(RSP), 8); R(RSP) += 8; @@ -82,7 +106,28 @@ IMPL_START(pop) return 1; } -IMPL_START(call) +IMPL_START(pop, 2) +{ + *r1 = readmemzx(R(RSP) + 0, 8); + *r2 = readmemzx(R(RSP) + 8, 8); + R(RSP) += 16; + + return 2; +} + +IMPL_START(pop, 3) +{ + *r1 = readmemzx(R(RSP) + 0, 8); + *r2 = readmemzx(R(RSP) + 8, 8); + *r3 = readmemzx(R(RSP) + 16, 8); + R(RSP) += 24; + + return 3; +} + +//----------------------------------------------------------------------------// + +IMPL_START(call, 1) { SRCP(p1); @@ -93,7 +138,7 @@ IMPL_START(call) return 0; } -IMPL_START(xcall2) +IMPL_START(call, 2) { SRCP(p1); SRCP(p2); @@ -107,7 +152,7 @@ IMPL_START(xcall2) return 0; } -IMPL_START(xcall3) +IMPL_START(call, 3) { SRCP(p1); SRCP(p2); @@ -123,7 +168,9 @@ IMPL_START(xcall3) return 0; } -IMPL_START(ret) +//----------------------------------------------------------------------------// + +IMPL_START(ret, 0) { R(RIP) = readmemzx(R(RSP), 8); R(RSP) += 8; @@ -131,7 +178,16 @@ IMPL_START(ret) return 0; } -IMPL_START(enter) +IMPL_START(enter, 0) +{ + R(RSP) -= 8; + writemem(R(RBP), R(RSP), 8); + R(RBP) = R(RSP); + + return 0; +} + +IMPL_START(enter, 1) { writemem(R(RBP), R(RSP) - 8, 8); R(RBP) = R(RSP) - 8; @@ -140,7 +196,7 @@ IMPL_START(enter) return 0; } -IMPL_START(leave) +IMPL_START(leave, 0) { R(RSP) = R(RBP) + 8; R(RBP) = readmemzx(R(RBP), 8); diff --git a/vm/in/misc.c b/vm/in/misc.c index a17ac6d..e28faf8 100644 --- a/vm/in/misc.c +++ b/vm/in/misc.c @@ -9,13 +9,13 @@ //----------------------------------------------------------------------------// -IMPL_START(into) { INTO(); return 0; } -IMPL_START(pause) { usleep(5000); return 0; } -IMPL_START(udf) { _except(E_UDF, "UDF instruction"); } +IMPL_START(into, 0) { INTO(); return 0; } +IMPL_START(pause, 0) { usleep(5000); return 0; } +IMPL_START(udf, 0) { _except(E_UDF, "UDF instruction"); } //----------------------------------------------------------------------------// -IMPL_START(break) +IMPL_START(break, 0) { #ifndef NDEBUG trace("\nExecuting BREAK INSTR\n"); @@ -28,7 +28,7 @@ IMPL_START(break) return 0; } -IMPL_START(dump) +IMPL_START(dump, 0) { #ifndef NDEBUG if (ctx->dumpsw) @@ -44,7 +44,7 @@ IMPL_START(dump) //----------------------------------------------------------------------------// -IMPL_START(ytime) +IMPL_START(ytime, 3) { time_t t = time(NULL); struct tm *tm = localtime(&t); @@ -59,7 +59,7 @@ IMPL_START(ytime) return 3; } -IMPL_START(utime) +IMPL_START(utime, 1) { struct timeval time; gettimeofday(&time, NULL); @@ -70,7 +70,7 @@ IMPL_START(utime) //----------------------------------------------------------------------------// -IMPL_START(cls) +IMPL_START(cls, 0) { R(RFX) = 0; for (int i = RAX; i <= R20; i++) R(i) = 0; @@ -80,7 +80,7 @@ IMPL_START(cls) //----------------------------------------------------------------------------// -IMPL_START(bswap) +IMPL_START(bswap, 2) { SRCP(p2); @@ -98,7 +98,7 @@ IMPL_START(bswap) return 1; } -IMPL_START(wswap) +IMPL_START(wswap, 2) { SRCP(p2); @@ -112,7 +112,7 @@ IMPL_START(wswap) return 1; } -IMPL_START(dswap) +IMPL_START(dswap, 2) { SRCP(p2); @@ -128,7 +128,7 @@ IMPL_START(dswap) #define PRN_CLEAR_MAGIC 0x8BF00001 #define PRN_FLUSH_MAGIC 0x8BF00002 -IMPL_START(prn) +IMPL_START(prn, 1) { SRCP(p1); @@ -158,7 +158,7 @@ IMPL_START(prn) return 0; } -IMPL_START(prns) +IMPL_START(prns, 1) { if (p1->type != A_REG) _except(E_ILL, "PRNS given a non-REG operand"); @@ -180,7 +180,7 @@ IMPL_START(prns) return 0; } -IMPL_START(scan) +IMPL_START(scan, 1) { *r1 = console_scankeybuf(); diff --git a/vm/in/string.c b/vm/in/string.c index 4d04e2f..878f19c 100644 --- a/vm/in/string.c +++ b/vm/in/string.c @@ -20,10 +20,10 @@ static void stos_impl(acc_t *p1, acc_t *p2, uint len) STR_MOVE(p1->reg, len); } -IMPL_START(stosb) { stos_impl(p1, p2, 1); return 0; } -IMPL_START(stosw) { stos_impl(p1, p2, 2); return 0; } -IMPL_START(stosd) { stos_impl(p1, p2, 4); return 0; } -IMPL_START(stosq) { stos_impl(p1, p2, 8); return 0; } +IMPL_START(stosb, 2) { stos_impl(p1, p2, 1); return 0; } +IMPL_START(stosw, 2) { stos_impl(p1, p2, 2); return 0; } +IMPL_START(stosd, 2) { stos_impl(p1, p2, 4); return 0; } +IMPL_START(stosq, 2) { stos_impl(p1, p2, 8); return 0; } //----------------------------------------------------------------------------// @@ -44,10 +44,10 @@ static void scas_impl(acc_t *p1, acc_t *p2, uint len) } } -IMPL_START(scasb) { scas_impl(p1, p2, 1); return 0; } -IMPL_START(scasw) { scas_impl(p1, p2, 2); return 0; } -IMPL_START(scasd) { scas_impl(p1, p2, 4); return 0; } -IMPL_START(scasq) { scas_impl(p1, p2, 8); return 0; } +IMPL_START(scasb, 2) { scas_impl(p1, p2, 1); return 0; } +IMPL_START(scasw, 2) { scas_impl(p1, p2, 2); return 0; } +IMPL_START(scasd, 2) { scas_impl(p1, p2, 4); return 0; } +IMPL_START(scasq, 2) { scas_impl(p1, p2, 8); return 0; } //----------------------------------------------------------------------------// diff --git a/vm/in/super.c b/vm/in/super.c index 1730e0a..b760666 100644 --- a/vm/in/super.c +++ b/vm/in/super.c @@ -31,20 +31,20 @@ void do_hlt() //----------------------------------------------------------------------------// -IMPL_START(hlt) { CHK_SUPERV(); do_hlt(); return 0; } -IMPL_START(stop) { CHK_SUPERV(); _except(E_SHT, "STOP INSTR"); } -IMPL_START(crash) { CHK_SUPERV(); _except(1023, "CRASH instruction"); } +IMPL_START(hlt, 0) { CHK_SUPERV(); do_hlt(); return 0; } +IMPL_START(stop, 0) { CHK_SUPERV(); _except(E_SHT, "STOP INSTR"); } +IMPL_START(crash, 0) { CHK_SUPERV(); _except(1023, "CRASH instruction"); } //----------------------------------------------------------------------------// -IMPL_START(trap) +IMPL_START(trap, 1) { if (p1->val > 255) _except(E_ILL, "TRAP number greater than 255"); _except(p1->val + 256, "TRAP instruction"); } -IMPL_START(iret) { +IMPL_START(iret, 0) { if (ctx->dumpsw) trace("\nReturning from exception #%ld\n\n", R(R13)); @@ -56,8 +56,8 @@ IMPL_START(iret) { return 0; } -IMPL_START(cli) { CHK_SUPERV(); R(CR0) &= ~IF; return 0; } -IMPL_START(sti) { CHK_SUPERV(); R(CR0) |= IF; return 0; } +IMPL_START(cli, 0) { CHK_SUPERV(); R(CR0) &= ~IF; return 0; } +IMPL_START(sti, 0) { CHK_SUPERV(); R(CR0) |= IF; return 0; } //----------------------------------------------------------------------------// @@ -76,7 +76,7 @@ dev_t *devctl_common(ulong idx) return NULL; } -IMPL_START(devctl) +IMPL_START(devctl, 2) { CHK_SUPERV(); @@ -98,7 +98,7 @@ IMPL_START(devctl) return 0; } -IMPL_START(iocall) +IMPL_START(iocall, 2) { CHK_SUPERV(); diff --git a/vm/pc/decode.c b/vm/pc/decode.c index af94461..0a3272f 100644 --- a/vm/pc/decode.c +++ b/vm/pc/decode.c @@ -199,6 +199,8 @@ void decode(void) ushort b1, b2, rep = 0, lock; acc_t p1 = { 0 }, p2 = { 0 }, p3 = { 0 }; + //logerr("decodin'\n"); + ctx->cur_pc = R(RIP); // Address range check diff --git a/vm/pc/exec.c b/vm/pc/exec.c index 8f63221..d9d3517 100644 --- a/vm/pc/exec.c +++ b/vm/pc/exec.c @@ -66,7 +66,7 @@ void exec_instr(instr_t *in, // For REPs we evaluate the condition AFTER running the instruction, // in a do ... while(cond) fashion // - if (ctx->cond && in->func != i_b) // 'B' instruction is special + if (ctx->cond && in->func != i_bch_3) // 'B' instruction is special if (!rep && !eval_cond(ctx->cond)) return; diff --git a/vm/pc/main.c b/vm/pc/main.c index effe1aa..70ab912 100644 --- a/vm/pc/main.c +++ b/vm/pc/main.c @@ -13,21 +13,10 @@ static ushort *fwprog; ctx_t main_ctx; -void sigcommon(void) -{ - _except(E_BRK, "SIGNAL'ed"); -} +void sigcommon(void) { _except(E_BRK, "SIGNAL'ed"); } +void sigint(int _) { sigcommon(); } -void sigint(int _) -{ - sigcommon(); -} - -void sigsegv(int _) -{ - logerr("Segmentation fault\n"); - sigcommon(); -} +void sigsegv(int _) { logerr("\nCaught: Segmentation fault\n\n"); dumpregs(); die(1); } jmp_buf exc_jmp_buf; @@ -38,16 +27,12 @@ void main_loop(void) { setjmp(exc_jmp_buf); - // // Start decoding - // while (!dying) { // Execute one instruction decode(); - console_update(); } - die(0); } @@ -55,13 +40,13 @@ int main(int argc, char **argv) { FILE *fwfile; - main_ctx.r = arch_r; - main_ctx.i = arch_i; - #if 0 && !defined(NDEBUG) main_ctx.dumpsw = 1; #endif + main_ctx.r = arch_r; + main_ctx.i = arch_i; + // // srand // diff --git a/vm/pc/mem.c b/vm/pc/mem.c index 4758ea0..2df44d3 100644 --- a/vm/pc/mem.c +++ b/vm/pc/mem.c @@ -162,8 +162,6 @@ void writemem(ulong val, ulong addr, uint len) GETREAL(); CHK_RANGE(); - // log("writemem: 0x%lX: 0x%lX (%d)\n", addr, val, len); - switch (len) { case 1: writemem8(val, real, addr); break; case 2: writemem16(val, real, addr); break;