diff --git a/as/k-as.py b/as/k-as.py index 59d728a..1b86c4e 100755 --- a/as/k-as.py +++ b/as/k-as.py @@ -369,52 +369,6 @@ def parse_preproc(line): #------------------------------------------------------------------------------- -pconds = { - 'c': 0b00001, - 'o': 0b00010, - 'z': 0b00011, - 'e': 0b00011, - 's': 0b00100, - - 'pe': 0b00101, - 'po': 0b10101, - - 'b': 0b00001, - 'be': 0b00110, - 'l': 0b00111, - 'le': 0b01000, - - 'a': 0b10110, # nbe - 'ae': 0b10001, # nb - 'g': 0b11000, # nle - 'ge': 0b10111, # nl - - 'axz': 0b01001, - 'bxz': 0b01010, - 'cxz': 0b01011, - 'dxz': 0b01100, - - 'axnz': 0b11001, - 'bxnz': 0b11010, - 'cxnz': 0b11011, - 'dxnz': 0b11100, -} - -def get_cond_mask(cond, line): - mask = 0 - - if cond[0] == 'n': - cond = cond[1:] - mask = 0b10000 - - if cond not in pconds: - print("Invalid condition suffix: {}".format(line)) - leave(1) - - return (mask | pconds[cond]) - -#------------------------------------------------------------------------------- - fmts = { "r": 0b00000000, "m_r": 0b00100000, @@ -456,40 +410,11 @@ def parse_instr(line): params = None size = 1 - - # Byte 2 (rep|lock|0|cond) - b2 = 0 - - if len(instr) > 2 and '.' in instr: - instr, suf = instr.split('.', 1) - - if len(instr) == 0: - print("Missing instruction name before suffixes: {}".format(line)) - - if len(suf) > 2 and suf[:3] == "rep": - if len(suf) > 3: - suf = suf[3:] - - if len(suf) > 0 and suf[0] == '.': - suf = suf[1:] - else: - suf = '' - - b2 |= 1<<7 # REP - - if len(suf) > 0: - b2 |= get_cond_mask(suf, line) - instr_name = instr instr_args = '' if params == None or len(params) == 0: - if b2 == 0: - instrs.write("{}_0".format(instr_name)) - - else: - size += 1 - instrs.write("%%suff {}_0 %%imm8 {}".format(instr_name, b2)) + instrs.write("{}_0".format(instr_name)) return size @@ -721,19 +646,13 @@ def parse_instr(line): instr_args += word - if b2 == 0: - instrs.write("{} {}".format(instr_name, instr_args)) - - else: - size += 1 - instrs.write("%%suff {} %%imm8 {} {}".format(instr_name, b2, instr_args)) + instrs.write("{}{}".format(instr_name, instr_args)) return size #------------------------------------------------------------------------------- special_syms = { - "%%suff", "%%imm8", "%%imm16", "%%imm32", @@ -749,7 +668,6 @@ def gentext(): data_start += (8 - data_start % 8) instrs.seek(0) - suff_mask = 0 for _, line in enumerate(instrs): tok = line.strip().split() @@ -769,9 +687,8 @@ def gentext(): continue if word in pinstrs: - idx = pinstrs.index(word) | suff_mask + idx = pinstrs.index(word) b_text.write(idx.to_bytes(1, byteorder='little', signed=False)) - suff_mask = 0 continue if word in plabels_text: @@ -785,9 +702,7 @@ def gentext(): continue if word in special_syms: - if word == "%%suff": - suff_mask = 1<<7 - elif word == "%%imm8": + if word == "%%imm8": lastimm = 1 elif word == "%%imm16": lastimm = 2 diff --git a/as/regs.lst b/as/regs.lst index 74376a0..b47bcdc 100644 --- a/as/regs.lst +++ b/as/regs.lst @@ -1,18 +1,10 @@ -$rzx $zero -$cr0 -$cr1 -$cr2 -$rfx -$rip -$rbp -$rsp - $rax $r0 $rbx $r1 $rcx $r2 $rdx $r3 $rsi $r4 $rdi $r5 + $ax0 $r6 $ax1 $r7 $ax2 $r8 @@ -29,6 +21,19 @@ $nx5 $r17 $nx6 $r18 $nx7 $r19 $nx8 $r20 + $grp $r21 $trp $r22 -$srp $r22 +$srp $r23 + +$tmp $r24 +$rad $r25 + +$cr0 $r26 +$cr1 $r27 + +$rip $r28 +$rbp $r29 +$rsp $r30 + +$zero $r31 diff --git a/ka/crt/crt.k b/ka/crt/crt.k index 8813b0c..a6dd85b 100644 --- a/ka/crt/crt.k +++ b/ka/crt/crt.k @@ -5,47 +5,49 @@ ; Limits ; -CHAR_MIN := 0x0000000000000080 -SHRT_MIN := 0x0000000000008000 -INT_MIN := 0x0000000080000000 +CHAR_MIN := 0x80 +SHRT_MIN := 0x8000 +INT_MIN := 0x80000000 LONG_MIN := 0x8000000000000000 XCHAR_MIN := 0xFFFFFFFFFFFFFF80 XSHRT_MIN := 0xFFFFFFFFFFFF8000 XINT_MIN := 0xFFFFFFFF80000000 -CHAR_MAX := 0x000000000000007F -SHRT_MAX := 0x0000000000007FFF -INT_MAX := 0x000000007FFFFFFF +CHAR_MAX := 0x7F +SHRT_MAX := 0x7FFF +INT_MAX := 0x7FFFFFFF LONG_MAX := 0x7FFFFFFFFFFFFFFF -BYTE_MAX := 0x00000000000000FF -WORD_MAX := 0x000000000000FFFF -LWORD_MAX := 0x00000000FFFFFFFF +BYTE_MAX := 0xFF +WORD_MAX := 0xFFFF +LWORD_MAX := 0xFFFFFFFF QWORD_MAX := 0xFFFFFFFFFFFFFFFF -FILE_MAXSZ := 0x0000000000008000 -STRLEN_MAX := 0x000000007AFFFFFF -FNAME_MAX := 0x0000000000000080 +FNAME_MAX := 0x80 +FILE_MAXSZ := 0x8000 +STRLEN_MAX := 0x7AFFFFFF ; ; Magic numbers ; -PRN_CLEAR := 0x000000008BF00001 -PRN_FLUSH := 0x000000008BF00002 +PRN_CLEAR := 0x8BF00001 +PRN_FLUSH := 0x8BF00002 ; ; CRT librairies ; include "crt/sys.k" -include "crt/err/errno.k" -include "crt/fmt/format.k" -include "crt/str/string.k" -include "crt/mem/memory.k" -include "crt/lib/time.k" +include "crt/str.k" +include "crt/mem.k" +include "crt/time.k" +include "crt/fmt/ltostr.k" +include "crt/fmt/strtol.k" +include "crt/fmt/doprnt.k" +include "crt/fmt/printf.k" abort: crash diff --git a/ka/crt/err/errno.k b/ka/crt/err/errno.k deleted file mode 100644 index ee3a284..0000000 --- a/ka/crt/err/errno.k +++ /dev/null @@ -1,7 +0,0 @@ -; The OS/K Team licenses this file to you under the MIT license. -; See the LICENSE file in the project root for more information. - -EINVAL := 1 -errno = 0 - -EOK := 0 diff --git a/ka/crt/fmt/doprnt.k b/ka/crt/fmt/doprnt.k index f01353e..46cc890 100644 --- a/ka/crt/fmt/doprnt.k +++ b/ka/crt/fmt/doprnt.k @@ -15,14 +15,14 @@ doprnt: mov r12, ax2 ; fmt mov r14, ax3 ; va_list mov r15, ax1 ; n - mov r16, zero ; return value mov r17, ax0 ; putc + nul r16 ; return value .main_loop: ; find '%' or null-terminator mov rcx, STRLEN_MAX mov r13, r12 - scasb.rep.nz r13, '%' + scasb r13, '%' ; everything below r13 is a regular character; print it .print_regular: @@ -62,7 +62,7 @@ doprnt: bzr r13, .nullstring .print_string: - mov ax0, b[r13] + movzx ax0, b[r13] bzr ax0, .main_loop inc r13, 1 @@ -107,7 +107,7 @@ doprnt: inc r14, 8 .print_itoa_buf: - mov ax0, b[r13] + movzx ax0, b[r13] bzr ax0, .pib_end_loop inc r13, 1 @@ -144,8 +144,9 @@ doprnt: .epilogue: mov rax, r16 - pop r17, r16, r15 - pop r14, r13, r12 + pop r17, r16 + pop r15, r14 + pop r13, r12 leave ret @@ -170,7 +171,7 @@ doprnt: jraxz .r ; yes, so artificially set n=0 - mov r15, zero + nul r15 .r: ret diff --git a/ka/crt/fmt/format.k b/ka/crt/fmt/format.k deleted file mode 100644 index a79e79e..0000000 --- a/ka/crt/fmt/format.k +++ /dev/null @@ -1,8 +0,0 @@ -; The OS/K Team licenses this file to you under the MIT license. -; See the LICENSE file in the project root for more information. - -include "crt/fmt/ltostr.k" -include "crt/fmt/strtol.k" -include "crt/fmt/doprnt.k" -include "crt/fmt/printf.k" - diff --git a/ka/crt/fmt/ltostr.k b/ka/crt/fmt/ltostr.k index 304cd8c..dc6e3a2 100644 --- a/ka/crt/fmt/ltostr.k +++ b/ka/crt/fmt/ltostr.k @@ -12,7 +12,7 @@ itoa: ; void utoa(char *buf, int num, int base) ; utoa: - mov ax3, zero + nul ax3 jmp ltostr ; @@ -20,7 +20,7 @@ utoa: ; ltostr: mov rax, ax0 - mov rcx, zero + nul rcx ; make sure base is in [2, 32] bltu ax2, 2, .bad @@ -37,7 +37,7 @@ ltostr: shr rcx, ax1, 63 ; extract ax1 sign jrcxz .conv - sub ax1, zero, ax1 ; NEG if negative + neg ax1 ; NEG if negative ; main loop .conv: @@ -68,7 +68,7 @@ ltostr: inc ax0, 1 .cxz: - mov b[ax0], zero + nul b[ax0] call strrev2, rax ret @@ -77,7 +77,6 @@ ltostr: ; exceptional cases ; .bad: - mov q[errno], EINVAL mov b[ax0], 0 ret diff --git a/ka/crt/fmt/printf.k b/ka/crt/fmt/printf.k index 02a8fbd..657449b 100644 --- a/ka/crt/fmt/printf.k +++ b/ka/crt/fmt/printf.k @@ -6,7 +6,7 @@ ; putc: prn ax0 - mov rax, zero + nul rax ret ; diff --git a/ka/crt/fmt/strtol.k b/ka/crt/fmt/strtol.k index 9494a4d..be06c57 100644 --- a/ka/crt/fmt/strtol.k +++ b/ka/crt/fmt/strtol.k @@ -18,7 +18,7 @@ strtol: ; rdx = pointer to first invalid byte ; strtoul: - mov ax2, zero + nul ax2 jmp strtoq ; @@ -27,8 +27,7 @@ strtoul: ; guesses base when 'base'=0 ; strtoq: - mov rax, zero - mov rsi, zero + nul rax, rsi mov rdx, ax0 ; make sure base is in [2, 32] @@ -158,12 +157,11 @@ strtoq: bzr rsi, .r ; yes - sub rax, zero, rax + neg rax .r: ret .bad: - mov q[errno], EINVAL ret diff --git a/ka/crt/mem/memory.k b/ka/crt/mem.k similarity index 95% rename from ka/crt/mem/memory.k rename to ka/crt/mem.k index 6004199..196efc6 100644 --- a/ka/crt/mem/memory.k +++ b/ka/crt/mem.k @@ -24,7 +24,7 @@ memzero: jrcxz .r .l: - mov b[ax0], zero + nul b[ax0] inc ax0, 1 loop .l diff --git a/ka/crt/str.k b/ka/crt/str.k new file mode 100644 index 0000000..0b72b2b --- /dev/null +++ b/ka/crt/str.k @@ -0,0 +1,222 @@ +; The OS/K Team licenses this file to you under the MIT license. +; See the LICENSE file in the project root for more information. + +; +; int strnlen(char *, int) +; +strnlen: + mov rcx, ax1 + scasb ax0, zero + + sub rax, ax1, rcx + ret + +; +; int strlen(char *) +; +strlen: + mov rcx, STRLEN_MAX + mov rdx, rcx + scasb ax0, zero + + sub rax, rdx, rcx + ret + +; +; void strcpy(char *, const char *) +; +strcpy: +.l: + mov rcx, b[ax1] + mov b[ax0], rcx + + jrcxz .r + + inc ax0, 1 + inc ax1, 1 + + jmp .l + +.r: + ret + +; +; void strncpy(char *, const char *, int) +; +strncpy: + mov rcx, ax2 + jrcxz .r + +.l: + mov b[ax0], b[ax1] + + inc ax0, 1 + inc ax1, 1 + + loop .l + +.r: + ret + +; +; void strnzcpy(char *, const char *, int) +; +strnzcpy: + mov rcx, ax2 + jrcxz .r + +.l: + mov rax, b[ax1] + mov b[ax0], rax + + jraxz .r + + inc ax0, 1 + inc ax1, 1 + + loop .l + +.z: + nul b[ax0] + +.r: + ret + +; +; int strcmp(const char *str1, const char *str2) +; +; Returns: +; 0 if the contents of both strings are equal +; >0 if the first character that does not match has a greater value in str1 than in str2 +; <0 if the first character that does not match has a lower value in str1 than in str2 +; +strcmp: + nul rsi +.l: + movzx rax, b[ax0+rsi] + movzx rdx, b[ax1+rsi] + + bne rax, rdx, .r + + ; both zero? + add rcx, rax, rdx + jrcxz .r + + inc rsi, 1 + jmp .l + +.r: + dec rax, rdx + ret + +; +; int strncmp(const char *str1, const char *str2, int maxn) +; +strncmp: + mov rcx, ax2 + jrcxz .r + +.l: + movzx rax, b[ax0] + movzx rdx, b[ax1] + + bne rax, rdx, .r + + inc ax0, 1 + inc ax1, 1 + loop .l + +.r: + dec rax, rdx + ret + +; +; char *strchrnul(const char *str, int ch) +; +strchrnul: + mov rcx, STRLEN_MAX + scasb ax0, ax1 + + mov rax, ax0 + ret + +; +; char *strchr(const char *str, int ch) +; +strchr: + mov rcx, STRLEN_MAX + scasb ax0, ax1 + + bnz b[ax0], .r + nul rax + ret + +.r: + mov rax, ax0 + ret + +; +; void strrev(char *buf, const char *str) +; +; buf and src must NOT overlap +; +strrev: + bzr b[ax1], .z + + ; save str's location + mov rsi, ax1 + + ; go to str's end, just before + ; the null terminator + mov rcx, STRLEN_MAX + scasb ax1, zero + dec ax1, 1 + +.l: + ; copy, going backward though str + ; and forward through buf + mov b[ax0], b[ax1] + + beq ax1, rsi, .r + + inc ax0, 1 + dec ax1, 1 + jmp .l + +.r: + nul b[ax0+1] + ret + +.z: + nul b[ax0] + ret + +; +; void strrev2(char *str) +; +; Inverses str +; +strrev2: + bzr b[ax0], .r + + mov ax1, ax0 + + ; go to str's end, just before + ; the null terminator + mov rcx, STRLEN_MAX + scasb ax1, zero + dec ax1, 1 + + ; increase ax0 while decreasing ax1, performing exchanges +.l: + blteu ax1, ax0, .r + + xchg b[ax0], b[ax1] + + inc ax0, 1 + dec ax1, 1 + jmp .l + +.r: + ret + diff --git a/ka/crt/str/strchr.k b/ka/crt/str/strchr.k deleted file mode 100644 index e3d3967..0000000 --- a/ka/crt/str/strchr.k +++ /dev/null @@ -1,27 +0,0 @@ -; The OS/K Team licenses this file to you under the MIT license. -; See the LICENSE file in the project root for more information. - -; -; char *strchrnul(const char *str, int ch) -; -strchrnul: - mov rcx, STRLEN_MAX - scasb.rep.nz ax0, ax1 - - mov rax, ax0 - ret - -; -; char *strchr(const char *str, int ch) -; -strchr: - mov rcx, STRLEN_MAX - scasb.rep.nz ax0, ax1 - - bnz b[ax0], .r - mov rax, zero - ret - -.r: - mov rax, ax0 - ret diff --git a/ka/crt/str/strcmp.k b/ka/crt/str/strcmp.k deleted file mode 100644 index 57f87a4..0000000 --- a/ka/crt/str/strcmp.k +++ /dev/null @@ -1,51 +0,0 @@ -; The OS/K Team licenses this file to you under the MIT license. -; See the LICENSE file in the project root for more information. - -; -; int strcmp(const char *str1, const char *str2) -; -; Returns: -; 0 if the contents of both strings are equal -; >0 if the first character that does not match has a greater value in str1 than in str2 -; <0 if the first character that does not match has a lower value in str1 than in str2 -; -strcmp: - mov rsi, zero -.l: - movzx rax, b[ax0+rsi] - movzx rdx, b[ax1+rsi] - - bne rax, rdx, .r - - ; both zero? - add rcx, rax, rdx - jrcxz .r - - inc rsi, 1 - jmp .l - -.r: - dec rax, rdx - ret - -; -; int strncmp(const char *str1, const char *str2, int maxn) -; -strncmp: - mov rcx, ax2 - jrcxz .r - -.l: - movzx rax, b[ax0] - movzx rdx, b[ax1] - - bne rax, rdx, .r - - inc ax0, 1 - inc ax1, 1 - loop .l - -.r: - dec rax, rdx - ret - diff --git a/ka/crt/str/strcpy.k b/ka/crt/str/strcpy.k deleted file mode 100644 index 10e395c..0000000 --- a/ka/crt/str/strcpy.k +++ /dev/null @@ -1,63 +0,0 @@ -; The OS/K Team licenses this file to you under the MIT license. -; See the LICENSE file in the project root for more information. - -; -; void strcpy(char *, const char *) -; -strcpy: -.l: - mov rcx, b[ax1] - mov b[ax0], rcx - - jrcxz .r - - inc ax0, 1 - inc ax1, 1 - - jmp .l - -.r: - ret - -; -; void strncpy(char *, const char *, int) -; -strncpy: - mov rcx, ax2 - jrcxz .r - -.l: - mov b[ax0], b[ax1] - - inc ax0, 1 - inc ax1, 1 - - loop .l - -.r: - ret - -; -; void strnzcpy(char *, const char *, int) -; -strnzcpy: - mov rcx, ax2 - jrcxz .r - -.l: - mov rax, b[ax1] - mov b[ax0], rax - - jraxz .r - - inc ax0, 1 - inc ax1, 1 - - loop .l - -.z: - mov b[ax0], zero - -.r: - ret - diff --git a/ka/crt/str/string.k b/ka/crt/str/string.k deleted file mode 100644 index ee9d229..0000000 --- a/ka/crt/str/string.k +++ /dev/null @@ -1,9 +0,0 @@ -; The OS/K Team licenses this file to you under the MIT license. -; See the LICENSE file in the project root for more information. - -include "crt/str/strlen.k" -include "crt/str/strrev.k" -include "crt/str/strcpy.k" -include "crt/str/strcmp.k" -include "crt/str/strchr.k" - diff --git a/ka/crt/str/strlen.k b/ka/crt/str/strlen.k deleted file mode 100644 index 355a4b4..0000000 --- a/ka/crt/str/strlen.k +++ /dev/null @@ -1,24 +0,0 @@ -; The OS/K Team licenses this file to you under the MIT license. -; See the LICENSE file in the project root for more information. - -; -; int strnlen(char *, int) -; -strnlen: - mov rcx, ax1 - scasb.rep.nz ax0, zero - - sub rax, ax1, rcx - ret - -; -; int strlen(char *) -; -strlen: - mov rcx, STRLEN_MAX - mov rdx, rcx - scasb.rep.nz ax0, zero - - sub rax, rdx, rcx - ret - diff --git a/ka/crt/str/strrev.k b/ka/crt/str/strrev.k deleted file mode 100644 index cbc97f1..0000000 --- a/ka/crt/str/strrev.k +++ /dev/null @@ -1,72 +0,0 @@ -; The OS/K Team licenses this file to you under the MIT license. -; See the LICENSE file in the project root for more information. - -; -; void strrev(char *buf, const char *str) -; -; buf and src must NOT overlap -; -strrev: - bzr b[ax1], .z - - ; save str's location - mov rsi, ax1 - - ; go to str's end, just before - ; the null terminator - mov rcx, STRLEN_MAX - scasb.rep.nz ax1, zero - dec ax1, 1 - -.l: - ; copy, going backward though str - ; and forward through buf - mov b[ax0], b[ax1] - - beq ax1, rsi, .r - - inc ax0, 1 - dec ax1, 1 - jmp .l - -.r: - mov b[ax0+1], zero - ret - -.z: - mov b[ax0], zero - ret - -; -; void strrev2(char *str) -; -; Inverses str -; -strrev2: - bzr b[ax0], .r - - mov ax1, ax0 - - ; go to str's end, just before - ; the null terminator - mov rcx, STRLEN_MAX - scasb.rep.nz ax1, zero - dec ax1, 1 - - ; increase ax0 while decreasing ax1, performing exchanges -.l: - blteu ax1, ax0, .r - - xchg b[ax0], b[ax1] - - inc ax0, 1 - dec ax1, 1 - jmp .l - -.r: - ret - - - - - diff --git a/ka/crt/lib/time.k b/ka/crt/time.k similarity index 78% rename from ka/crt/lib/time.k rename to ka/crt/time.k index da6d0e2..bfc006b 100644 --- a/ka/crt/lib/time.k +++ b/ka/crt/time.k @@ -45,32 +45,33 @@ DaysInYear: ; TIME *GetTimeUTC(void) ; GetTimeUTC: - ytime ax0, ax1, ax2 - mov rdx, .buf + ytime + + mov rdi, .buf ; seconds - rem rcx, ax0, 60 - mov b[rdx], rcx + rem rsi, rax, 60 + mov b[rdi], rsi ; minutes - div rcx, ax0, 60 - rem rcx, 60 - mov b[rdx+1], rcx + div rsi, rax, 60 + rem rsi, 60 + mov b[rdi+1], rsi ; hours - div rcx, ax0, 3600 - rem rcx, 24 - mov b[rdx+2], rcx + div rsi, rax, 3600 + rem rsi, 24 + mov b[rdi+2], rsi ; month days - div rcx, ax0, 3600*24 - mov b[rdx+3], rcx + div rsi, rax, 3600*24 + mov b[rdi+3], rsi ; month - mov b[rdx+4], ax1 + mov b[rdi+4], rbx ; years - mov w[rdx+6], ax2 + mov w[rdi+6], rcx ; ; ydays (TODO) diff --git a/ka/doskrnl.k b/ka/doskrnl.k index 8a3b711..a20e61a 100644 --- a/ka/doskrnl.k +++ b/ka/doskrnl.k @@ -26,7 +26,7 @@ start: mov rsp, DOSKRNL_STACK mov rbp, zero - ; dump + ;dump call main diff --git a/ka/mkstats.py b/ka/mkstats.py index 45f79af..520b19b 100755 --- a/ka/mkstats.py +++ b/ka/mkstats.py @@ -15,15 +15,13 @@ def mkstat(fp): if len(tok) == 0: continue - i = tok[0].split('.')[0] - - if len(i) == 0 or i in ';#@/': + if len(tok[0]) == 0 or tok[0] in ';#@/': continue - if i in instrs: - instrs[i] += 1 + if tok[0] in instrs: + instrs[tok[0]] += 1 else: - instrs[i] = 1 + instrs[tok[0]] = 1 for root, _, files in os.walk('.'): for f in files: diff --git a/ka/sys/dumprf.k b/ka/sys/dumprf.k index 9c9c120..57040c7 100644 --- a/ka/sys/dumprf.k +++ b/ka/sys/dumprf.k @@ -9,18 +9,12 @@ dumprf: mov r12, ax0 mov r13, rsp - call RFS.LoadReg, r12, $cr2 - push rax - call RFS.LoadReg, r12, $cr1 push rax call RFS.LoadReg, r12, $cr0 push rax - call RFS.LoadReg, r12, $rfx - push rax - call RFS.LoadReg, r12, $rip push rax @@ -33,7 +27,7 @@ dumprf: call RFS.LoadReg, r12, $trp push rax - push 0 # fixme + push zero # fixme call RFS.LoadReg, r12, $rbp push rax @@ -120,7 +114,7 @@ dumprf: leave ret -.dmp1 = "Environ #1:\nfrm=0d%d rip=0x%x rfx=0x%x\ncr0=0x%x cr1=0x%x cr2=0x%x\n\n" +.dmp1 = "Environ #1:\nfrm=0d%d rip=0x%x\ncr0=0x%x cr1=0x%x\n\n" .dmp2 = "Environ #2:\nrsp=0x%x rbp=0x%x ind=0d%d\ngrp=0x%x trp=0x%x srp=0x%x\n\n" .dmp3 = "Argument:\nax0=0x%x ax1=0x%x ax2=0x%x\nax3=0x%x ax4=0x%x ax5=0x%x\n\n" .dmp4 = "Volatile:\nrax=0x%x rbx=0x%x rcx=0x%x\nrdx=0x%x rsi=0x%x rdi=0x%x\n\n" diff --git a/ka/sys/intr/common.k b/ka/sys/intr/common.k index 8a62597..8c6d147 100644 --- a/ka/sys/intr/common.k +++ b/ka/sys/intr/common.k @@ -11,7 +11,7 @@ ScreenOfDeath: push ax1 call printf, .scr1 - pop zero + pop bnz r14, .not_con push .scr2_con diff --git a/ka/sys/intr/excepts.k b/ka/sys/intr/excepts.k index 6ca83c5..444a84d 100644 --- a/ka/sys/intr/excepts.k +++ b/ka/sys/intr/excepts.k @@ -18,7 +18,7 @@ DefaultExceptionHandler: .err_ukn = "Unknown exception number\0\0\0\0\0\0\0" .err_udf = "Undefined behaviour exception\0\0" -.err_ill = "Ill-formed exception exception\0" +.err_ill = "Illformed instruction exception" .err_acc = "Invalid memory access exception" .err_sys = "Supervisor-only exception used\0" .err_dbf = "Double fault exception~~~~~~~~\0" diff --git a/ka/sys/intr/trap0.k b/ka/sys/intr/trap0.k index a03ff79..dfee844 100644 --- a/ka/sys/intr/trap0.k +++ b/ka/sys/intr/trap0.k @@ -2,14 +2,14 @@ ; See the LICENSE file in the project root for more information. TrapHandlers.prolog: - mov rbp, zero + nul rbp - ; rax = caller's cr2 - call RFS.LoadReg, r14, $cr2 + ; rax = caller's cr1 + call RFS.LoadReg, r14, $cr1 ; we don't preserve the r12 we got mov r12, rax - mov rdx, zero + nul rdx jmp rcx @@ -105,12 +105,8 @@ DefaultTrapHandler: mov ax2, rcx call RFS.StoreReg, zero, $cr1 - ; Data offset - mov ax2, rcx - call RFS.StoreReg, zero, $cr2 - ; Return frame - mov r14, zero + nul r14 jmp .fini diff --git a/ka/usr/cmd/dir.k b/ka/usr/cmd/dir.k index affb0ef..d40787a 100644 --- a/ka/usr/cmd/dir.k +++ b/ka/usr/cmd/dir.k @@ -10,9 +10,9 @@ builtins.dir: push r12, r13 push r14, r15 - mov r12, zero # no. of files found - mov r13, zero # no. of directories found - mov r14, zero # total amount of bytes found + nul r12 # no. of files found + nul r13 # no. of directories found + nul r14 # total amount of bytes found call print, .dirmsg @@ -46,7 +46,7 @@ builtins.dir: mov rcx, FNAME_MAX mov rsi, .buf mov rdi, rsi - scasb.rep.nz rsi, '.' + scasb rsi, '.' ; print file name sub ax1, rsi, rdi diff --git a/ka/usr/cmd/main.k b/ka/usr/cmd/main.k index e670ab5..4c5fb87 100644 --- a/ka/usr/cmd/main.k +++ b/ka/usr/cmd/main.k @@ -21,14 +21,16 @@ main: .print_prompt: call print, prompt - ; empty argbuf + ; empty stuff call memzero, argbuf, argbuf.size - call nprint, argbuf, argbuf.size + call memzero, argv0, argbuf.size + nul q[argv1pos] + + # call nprint, argv0, argbuf.size ; iterator through argbuf - mov rcx, zero + nul rcx - mov q[argv1pos], zero .input_loop: pause @@ -51,7 +53,7 @@ main: ; yes, delete it dec rcx, 1 add rdx, rcx, argbuf - mov b[rdx], zero + nul b[rdx] ; update screen bzr b[stdin_echoing], .input_loop @@ -86,7 +88,7 @@ main: ; find first whitespace or null-terminator mov rcx, argbuf.size mov rdx, argbuf - scasb.rep.nz rdx, ' ' + scasb rdx, ' ' ; argv1 exists? if so, save its position mov rsi, rdx @@ -108,9 +110,6 @@ main: ; fallthrough .do_extract: - ; empty argv0 - call memzero, argv0, argbuf.size - ; how much do we copy? sub rcx, rdx, argbuf jrcxz .detect_builtin diff --git a/vm/dv/cpudev.c b/vm/dv/cpudev.c index 67eb1e3..2c2887d 100644 --- a/vm/dv/cpudev.c +++ b/vm/dv/cpudev.c @@ -250,6 +250,8 @@ long cpudev_idtdone(dev_t *dev) if (idt_handling[R(AX0)] == 0) _except(E_UDF, "cpudev: idtdone, not handling E/I #%u", R(AX0)); + //trace("IDT.DONE %lu\n", R(AX0)); + idt_handling[R(AX0)]--; return 0; diff --git a/vm/in/ALU b/vm/in/ALU index 5a5f83a..57b819d 100644 --- a/vm/in/ALU +++ b/vm/in/ALU @@ -5,113 +5,83 @@ # Logical instructions # #---------------------------------------------------------------------------# -# -# Bitwise OR operation -# -# $dest = $src1 OR $src2 -# +# Bitwise NOT +not 1 + +# Bitwise OR or 2 or 3 -# -# Bitwise AND operation -# -# $dest = $src1 AND $src2 -# +# Bitwise AND and 2 and 3 -# -# Bitwise XOR operation -# -# $dest = $src1 XOR $src2 -# +# Bitwise XOR xor 2 xor 3 -# -# Logical left/right shift (SHL/SHR) -# -# $dest = $src1 << $src2 (SHL) -# $dest = $src1 >> $src2 (SHR) -# +# Logical left/right shift shl 2 shl 3 shr 2 shr 3 -# -# Arithmetical right shift (SAR) -# -# $dest = $src1 >>> $src2 (SAR) -# +# Arithmetical right shift sar 2 sar 3 #---------------------------------------------------------------------------# # Arithmetic instructions # #---------------------------------------------------------------------------# -# -# Arithmetical ADD operation -# -# $dest1 = $src1 + $src2 -# + +# Negation +neg 1 + +# Negation but traps on $src == -2^N +negv 1 + +# Addition add 2 add 3 -# -# Arithmetical SUB operation -# -# $dest = $src1 - $src2 -# +# Addition but traps on overflow +addv 2 +addv 3 + +# Substraction sub 2 sub 3 -# -# Arithmetical MUL operation -# -# $dest = LO($src1 * $src2) -# +# Substraction but traps on underflow +subv 2 +subv 3 + +# Multiplication +# $dest = LO($src1 * $src2) mul 2 mul 3 -# Arithmetical unsigned MUL operation -# -# $dest1 = HI($dest2 * $src) -# $dest2 = LO($dest2 * $src) +# Multiplication (unsigned) +# $dest1 = HI($dest2 * $src) +# $dest2 = LO($dest2 * $src) # mulhi 3 -# Arithmetical signed MUL operation -# -# $dest1 = HI($dest2 ** $src) -# $dest2 = LO($dest2 ** $src) +# Multiplication (signed) +# $dest1 = HI($dest2 * $src) +# $dest2 = LO($dest2 * $src) # imulhi 3 -# -# Arithmetical unsigned DIV operation -# -# $dest = $src1 DIV $src2 -# -# Preserves all flags -# +# Division (unsigned) div 2 div 3 -# -# Arithmetical signed DIV operation -# -# $dest = $src1 IDIV $src2 -# +# Division (signed) idiv 2 idiv 3 -# -# Arithmetical modulo operation (REM) -# -# $dest = $src1 MOD $src2 -# +# Modulo/remainder rem 2 rem 3 diff --git a/vm/in/MEM b/vm/in/MEM index 0569436..5e36dea 100644 --- a/vm/in/MEM +++ b/vm/in/MEM @@ -57,14 +57,17 @@ push 3 # $1 = *RSP # RSP = RSP + 8 # +pop 0 pop 1 pop 2 -pop 3 #---------------------------------------------------------------------------# # Movement instructions # #---------------------------------------------------------------------------# +nul 1 +nul 2 + # # Load Effective Address (LEA) instruction # @@ -78,27 +81,22 @@ pop 3 lea 2 # -# Move data (MOV) instruction +# Move data (MOV/MOVU) instructions # -# $1 = SignExtend($2) +# $1 = SignExtend($2) (MOV) +# $1 = ZeroExtend($2) (MOVU) # mov 2 - -# -# Load from memory with zero-extension (MOVSX/MOVZX) instruction -# -# $1 = ZeroExtend($2) -# movzx 2 # -# Move with sign-extension (MOVSXx) instruction +# Move with sign-extension (MOVx) instruction # # $1 = SignExtend($2 & (2^(8 * sizeof(x)) - 1) # -movsxb 2 -movsxw 2 -movsxd 2 +movb 2 +movw 2 +movd 2 # # Exchange (XCHG) instruction diff --git a/vm/in/MISC b/vm/in/MISC index 45efa51..c6bd9c9 100644 --- a/vm/in/MISC +++ b/vm/in/MISC @@ -45,7 +45,7 @@ utime 1 # $2 = current month # $3 = current year # -ytime 3 +ytime 0 # # Clear all GPR registers except RBP/RSP diff --git a/vm/in/STRING b/vm/in/STRING index 8ac4f5d..535f35e 100644 --- a/vm/in/STRING +++ b/vm/in/STRING @@ -8,24 +8,18 @@ # # Scan string for a particular value (SCASx) # -# CMP([%1], $2) +# WHILE RCX > 0 DO +# RCX = RCX - 1 # -# IF ([%1] == 0) THEN -# ZF = 1 -# ELIF (ZF == 0) THEN -# IF (DF == 0) THEN -# %1 = %1 + sizeof(x) -# ELSE -# %1 = %1 - sizeof(x) -# FI +# IF ([%1] == 0) OR ([%1] == $2) THEN +# BREAK +# ELSE +# %1 = %1 + sizeof(x) # FI +# DONE # -# Sets CF, OF and SF according to the result of the comparison -# Sets ZF according to whether [%1] and $2 are equal, OR if [%1] is null # -# Notes: -# - Does not move past the value when found -# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()' +# Note: Does not move past the value when found # scasb 2 scasw 2 diff --git a/vm/in/alu.c b/vm/in/alu.c index 4e7ae99..fb3f037 100644 --- a/vm/in/alu.c +++ b/vm/in/alu.c @@ -8,71 +8,103 @@ //----------------------------------------------------------------------------// -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(not, 1) { SRCP(p1); *r1 = ~p1->val; return 1; } +IMPL_START(or, 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, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val & p2->val; return 1; } IMPL_START(and, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val & p3->val; return 1; } + +IMPL_START(xor, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val ^ p2->val; return 1; } IMPL_START(xor, 3) { SRCP(p2); SRCP(p3); *r1 = p2->val ^ 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, 2) { SRCP(p1); SRCP(p2); *r1 = p1->val >> p2->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(sar, 2) { + SRCP(p1); SRCP(p2); + *r1 = (ulong)((long)p1->val >> (long)p2->val); + return 1; +} +IMPL_START(sar, 3) { + SRCP(p2); SRCP(p3); + *r1 = (ulong)((long)p2->val >> (long)p3->val); + return 1; +} //----------------------------------------------------------------------------// +IMPL_START(neg, 1) { SRCP(p1); *r1 = ~p1->val + 1; return 1; } +IMPL_START(negv, 1) { + SRCP(p1); + + if (p1->val == (1ul<<63)) + _except(E_OVF, "Ineffective NEG operation (NEGV)"); + + *r1 = ~p1->val + 1; + + 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(addv, 2) { + SRCP(p1); SRCP(p2); + + ulong rs = p1->val + p2->val; + + if (((p1->val ^ rs) & (p2->val ^ rs)) >> 63) + _except(E_OVF, "Signed addition overflow (ADDV#2)"); + + *r1 = rs; + return 1; +} + +IMPL_START(addv, 3) { + SRCP(p2); SRCP(p3); + + ulong rs = p2->val + p3->val; + + if (((p2->val ^ rs) & (p3->val ^ rs)) >> 63) + _except(E_OVF, "Signed addition overflow (ADDV#3)"); + + *r1 = rs; + 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, 2) { +IMPL_START(subv, 2) { SRCP(p1); SRCP(p2); - p2->val += !!(R(RFX)&CF); - COMPARE_ADD(p1->val, p2->val); - *r1 = p1->val + p2->val; + ulong rs = p1->val - p2->val; + if (((p1->val ^ rs) & (p1->val ^ p2->val)) >> 63) + _except(E_OVF, "Signed substraction underflow (SUBV#2)"); + + *r1 = rs; return 1; } -IMPL_START(adcx, 3) { - SRCP(p2); SRCP(p3); - - p3->val += !!(R(RFX)&CF); - COMPARE_ADD(p2->val, p3->val); - *r1 = p2->val + p3->val; - - return 1; -} - -IMPL_START(sbbx, 2) { +IMPL_START(subv, 3) { SRCP(p1); SRCP(p2); - p2->val += !!(R(RFX)&CF); - COMPARE_SUB(p1->val, p2->val); - *r1 = p1->val - p2->val; + ulong rs = p2->val - p3->val; - return 1; -} - -IMPL_START(sbbx, 3) { - SRCP(p2); SRCP(p3); - - p3->val += !!(R(RFX)&CF); - COMPARE_SUB(p2->val, p3->val); - *r1 = p2->val - p3->val; + if (((p2->val ^ rs) & (p2->val ^ p3->val)) >> 63) + _except(E_OVF, "Signed substraction underflow (SUBV#3)"); + *r1 = rs; return 1; } diff --git a/vm/in/arch_i.py b/vm/in/arch_i.py index fa6f668..0c31480 100644 --- a/vm/in/arch_i.py +++ b/vm/in/arch_i.py @@ -54,7 +54,7 @@ def parse_2(fp): .format(deprecated, tok[0], n, tok[0], n)) hd.write("#else\n") 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" + hd.write("extern bool i_{}_{}(acc_t *, acc_t *, acc_t *, ulong *, ulong *);\n" .format(tok[0], n)) hd.write("#endif\n\n") diff --git a/vm/in/instrs.h b/vm/in/instrs.h index c1c925f..13ed995 100644 --- a/vm/in/instrs.h +++ b/vm/in/instrs.h @@ -7,7 +7,7 @@ #define IMPL_START(name, n) \ uint i_##name##_##n(acc_t *p1, acc_t *p2, acc_t *p3, \ - ulong *r1, ulong *r2, ulong *r3) \ + ulong *r1, ulong *r2) \ #define XSRCP(v, p, x) \ if (ACC_FMT_IS_MEM(p->type)) \ @@ -20,52 +20,6 @@ uint i_##name##_##n(acc_t *p1, acc_t *p2, acc_t *p3, \ //----------------------------------------------------------------------------// -#define INTO() \ - if (R(RFX) & OF) _except(E_OVF, "Overflow"); - -#define PARITY(v) __builtin_parity(v) - -#define SET_ZF(v) \ - R(RFX) = ((v) == 0 ? (R(RFX)|ZF) : (R(RFX)&~ZF)) - -#define SET_SF(v) \ - R(RFX) = ((long)(v) < 0 ? (R(RFX)|SF) : (R(RFX)&~SF)) - -#define SET_PF(v) \ - R(RFX) = (PARITY(v) == 1 ? (R(RFX)|PF) : (R(RFX)&~PF)) - -#define SET_ZSF(v) \ - SET_ZF(v); \ - SET_SF(v) - -//----------------------------------------------------------------------------// - -#define COMPARE_ADD(v1, v2) \ - ulong _u1 = (ulong)v1, _u2 = (ulong)v2, _u3 = (_u1 + _u2); \ - \ - if (_u1 + _u2 < _u2) R(RFX) |= CF; \ - else R(RFX) &= ~CF; \ - \ - if (((_u1 ^ _u3) & (_u2 ^ _u3)) >> 63) \ - R(RFX) |= OF; \ - else R(RFX) &= ~OF; \ - \ - SET_ZSF(_u3); - -#define COMPARE_SUB(v1, v2) \ - ulong _u1 = (ulong)v1, _u2 = (ulong)v2, _u3 = (_u1 - _u2); \ - \ - if (_u1 < _u2) R(RFX) |= CF; \ - else R(RFX) &= ~CF; \ - \ - if (((_u1 ^ _u3) & (_u1 ^ _u2)) >> 63) \ - R(RFX) |= OF; \ - else R(RFX) &= ~OF; \ - \ - SET_ZSF(_u3); - -//----------------------------------------------------------------------------// - #define CHK_SUPERV() \ do { \ if ((R(CR0) & UF) > 0) { \ diff --git a/vm/in/jmp.c b/vm/in/jmp.c index 0d1ba15..c14b608 100644 --- a/vm/in/jmp.c +++ b/vm/in/jmp.c @@ -13,6 +13,8 @@ IMPL_START(jrcxz, 1) { if (!R(RCX)) R(RIP) = p1->val; return 0; } IMPL_START(jraxnz, 1) { if (R(RAX)) R(RIP) = p1->val; return 0; } IMPL_START(jrcxnz, 1) { if (R(RCX)) R(RIP) = p1->val; return 0; } +//----------------------------------------------------------------------------// + IMPL_START(loop, 1) { if (R(RCX) > 0) { R(RCX)--; @@ -21,6 +23,17 @@ IMPL_START(loop, 1) { return 0; } +IMPL_START(loop, 2) { + SRCP(p1); + if (p1->val > 0) { + *r1 = p1->val-1; + R(RIP) = p2->val; + } + return 0; +} + +//----------------------------------------------------------------------------// + IMPL_START(bzr, 2) { SRCP(p1); if (p1->val == 0) R(RIP) = p2->val; return 0; } IMPL_START(bnz, 2) { SRCP(p1); if (p1->val != 0) R(RIP) = p2->val; return 0; } IMPL_START(bltz, 2) { SRCP(p1); if ((long)p1->val < 0) R(RIP) = p2->val; return 0; } @@ -34,24 +47,5 @@ IMPL_START(bltu, 3) { SRCP(p1); if (p1->val < p2->val) R(RIP) = p3->val; return IMPL_START(blte, 3) { SRCP(p1); if ((long)p1->val <= (long)p2->val) R(RIP) = p3->val; return 0; } IMPL_START(blteu, 3) { SRCP(p1); if (p1->val <= p2->val) R(RIP) = p3->val; return 0; } -IMPL_START(bch, 3) -{ - SRCP(p1); - SRCP(p2); +//----------------------------------------------------------------------------// - COMPARE_SUB(p1->val, p2->val); - - if (eval_cond(ctx->cond)) - R(RIP) = p3->val; - - return 0; -} - -IMPL_START(cmp, 2) -{ - SRCP(p1); - - COMPARE_SUB(p1->val, p2->val); - - return 0; -} diff --git a/vm/in/mem.c b/vm/in/mem.c index fd96393..9646238 100644 --- a/vm/in/mem.c +++ b/vm/in/mem.c @@ -6,12 +6,16 @@ //----------------------------------------------------------------------------// 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, 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(movb, 2) { SRCP(p2); *r1 = (ulong)(long)(char)p2->val; return 1; } +IMPL_START(movw, 2) { SRCP(p2); *r1 = (ulong)(long)(short)p2->val; return 1; } +IMPL_START(movd, 2) { SRCP(p2); *r1 = (ulong)(long)(int)p2->val; return 1; } + +IMPL_START(nul, 1) { *r1 = 0; return 1; } +IMPL_START(nul, 2) { *r1 = 0; *r2 = 0; return 2; } IMPL_START(xchg, 2) { @@ -64,6 +68,12 @@ IMPL_START(push, 3) //----------------------------------------------------------------------------// +IMPL_START(pop, 0) +{ + R(RSP) += 8; + return 0; +} + IMPL_START(pop, 1) { *r1 = readmemzx(R(RSP), 8); @@ -81,16 +91,6 @@ IMPL_START(pop, 2) 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) @@ -144,6 +144,14 @@ IMPL_START(ret, 0) return 0; } +IMPL_START(ret, 1) +{ + R(RIP) = readmemzx(R(RSP), 8); + R(RSP) += 8 + (p1->val * 8); + + return 0; +} + //----------------------------------------------------------------------------// IMPL_START(enter, 0) diff --git a/vm/in/misc.c b/vm/in/misc.c index e28faf8..021361f 100644 --- a/vm/in/misc.c +++ b/vm/in/misc.c @@ -9,7 +9,6 @@ //----------------------------------------------------------------------------// -IMPL_START(into, 0) { INTO(); return 0; } IMPL_START(pause, 0) { usleep(5000); return 0; } IMPL_START(udf, 0) { _except(E_UDF, "UDF instruction"); } @@ -35,7 +34,7 @@ IMPL_START(dump, 0) trace("0x%lX:\t...\n", ctx->cur_pc); else if (!ctx->dumpsw) - dump_instr(ctx->cur_in, p1, p2, p3, 0, 0); + dump_instr(ctx->cur_in, p1, p2, p3); ctx->dumpsw = !ctx->dumpsw; #endif @@ -44,19 +43,19 @@ IMPL_START(dump, 0) //----------------------------------------------------------------------------// -IMPL_START(ytime, 3) +IMPL_START(ytime, 0) { time_t t = time(NULL); struct tm *tm = localtime(&t); - *r1 = tm->tm_sec + tm->tm_min * 60 - + tm->tm_hour * 60 * 60 - + tm->tm_mday * 60 * 60 * 24; + R(RAX) = tm->tm_sec + tm->tm_min * 60 + + tm->tm_hour * 60 * 60 + + tm->tm_mday * 60 * 60 * 24; - *r2 = tm->tm_mon; - *r3 = tm->tm_year + 1900; + R(RBX) = tm->tm_mon; + R(RCX) = tm->tm_year + 1900; - return 3; + return 0; } IMPL_START(utime, 1) @@ -72,7 +71,6 @@ IMPL_START(utime, 1) IMPL_START(cls, 0) { - R(RFX) = 0; for (int i = RAX; i <= R20; i++) R(i) = 0; return 0; @@ -148,6 +146,8 @@ IMPL_START(prn, 1) break; default: + trace("PRN bad magic: %lx\n", v); + die(1); _except(E_ILL, "Bad PRN magic"); } } @@ -158,28 +158,6 @@ IMPL_START(prn, 1) return 0; } -IMPL_START(prns, 1) -{ - if (p1->type != A_REG) - _except(E_ILL, "PRNS given a non-REG operand"); - - uchar ch = readmemzx(R(p1->reg), 1); - - COMPARE_SUB(ch, 0); - - if ((R(RFX) & ZF) == 0) - { - console_putc(ch); - - if (R(RFX) & DF) - R(p1->reg)--; - else - R(p1->reg)++; - } - - return 0; -} - IMPL_START(scan, 1) { *r1 = console_scankeybuf(); diff --git a/vm/in/string.c b/vm/in/string.c index 878f19c..6ab7338 100644 --- a/vm/in/string.c +++ b/vm/in/string.c @@ -11,36 +11,21 @@ //----------------------------------------------------------------------------// -static void stos_impl(acc_t *p1, acc_t *p2, uint len) -{ - if (p1->type != A_REG) - _except(E_ILL, "STOSX given a non-REG operand"); - - writemem(p2->val, R(p1->reg), len); - STR_MOVE(p1->reg, len); -} - -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; } - -//----------------------------------------------------------------------------// - static void scas_impl(acc_t *p1, acc_t *p2, uint len) { if (p1->type != A_REG) _except(E_ILL, "SCASX given a non-REG operand"); - ulong x = readmemsx(R(p1->reg), len); - COMPARE_SUB(x, p2->val); + while (R(RCX) > 0) + { + ulong x = readmemzx(R(p1->reg), len); - if (x == 0) { - R(RFX) |= ZF; - } + if (x == 0 || x == p2->val) + break; - else if (!(R(RFX)&ZF)) { - STR_MOVE(p1->reg, len); + R(p1->reg) += len; + + R(RCX)--; } } diff --git a/vm/pc/DECD b/vm/pc/DECD index a2d0979..6d684fd 100644 --- a/vm/pc/DECD +++ b/vm/pc/DECD @@ -3,11 +3,7 @@ Instruction encoding: -Byte 1: Instruction number -Byte 2: -xx0xxxxx -|| └───┘ -RL CND +Byte: Instruction number Values for ModRMs: 000xxxxx xxxxx = reg @@ -24,19 +20,3 @@ Values for ModRMs: 11100100 imm32 (zero extended) 11101000 imm64 (zero extended) -Values for COND: -00000 (none) -00001 .C .B -00010 .O -00011 .Z .E -00100 .S -00101 .P -00110 .BE -00111 .L -01000 .LE -01001 .AXZ -01010 .BXZ -01011 .CXZ -01100 .DXZ -Highest (6th) bit of COND indicates negation - diff --git a/vm/pc/arch.h b/vm/pc/arch.h index 79cd465..7fc294a 100644 --- a/vm/pc/arch.h +++ b/vm/pc/arch.h @@ -72,9 +72,6 @@ struct ctx_t ulong ninstrs; // totally ulong ni_thisfr; // this frame - // Last COND field - uint cond; - // Dumpinstr switch bool dumpsw; }; diff --git a/vm/pc/decode.c b/vm/pc/decode.c index 0a3272f..bdca68f 100644 --- a/vm/pc/decode.c +++ b/vm/pc/decode.c @@ -195,8 +195,8 @@ static void extract_param(instr_t *in, acc_t *p) // void decode(void) { + ushort b; instr_t *in; - ushort b1, b2, rep = 0, lock; acc_t p1 = { 0 }, p2 = { 0 }, p3 = { 0 }; //logerr("decodin'\n"); @@ -209,35 +209,20 @@ void decode(void) _except(E_ACC, "Executing out of memory"); // Instruction bytes - b1 = fetchb(); - - // Suffixes? - if (b1 & (1 << 7)) - { - b1 &= ~(1 << 7); - b2 = fetchb(); - } - - else - b2 = 0; + b = fetchb(); // Renge check - if (b1 >= NINSTRS) - _except(E_ILL, "No such INSTR: 0x%hhX", b1); + if (b >= NINSTRS) + _except(E_ILL, "No such INSTR: 0x%hhX", b); // Find instruction - in = &ctx->i[b1]; + in = &ctx->i[b]; ctx->cur_in = in; - // Get flags/etc - rep = !!(b2 & SUFF_REP); - lock = !!(b2 & SUFF_LOCK); - ctx->cond = b2 & SUFF_COND; - // Operand 1? if (in->nprms == 0) { - exec_instr(in, NULL, NULL, NULL, lock, rep); + exec_instr(in, NULL, NULL, NULL); return; } @@ -246,7 +231,7 @@ void decode(void) // Operand 2? if (in->nprms == 1) { - exec_instr(in, &p1, NULL, NULL, lock, rep); + exec_instr(in, &p1, NULL, NULL); return; } @@ -255,12 +240,12 @@ void decode(void) // Operand 1? if (in->nprms == 2) { - exec_instr(in, &p1, &p2, NULL, lock, rep); + exec_instr(in, &p1, &p2, NULL); return; } extract_param(in, &p3); - exec_instr(in, &p1, &p2, &p3, lock, rep); + exec_instr(in, &p1, &p2, &p3); } diff --git a/vm/pc/decode.h b/vm/pc/decode.h index 517a323..b84ea33 100644 --- a/vm/pc/decode.h +++ b/vm/pc/decode.h @@ -1,30 +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. -enum -{ - CD_NONE, - CD_C, - CD_O, - CD_Z, - CD_S, - CD_P, - CD_BE, - CD_L, - CD_LE, - CD_AXZ, - CD_BXZ, - CD_CXZ, - CD_DXZ, -}; - -enum -{ - SUFF_REP = (1 << 7), - SUFF_LOCK = (1 << 6), - SUFF_COND = 0b00011111, -}; - enum { A_NONE = 0, @@ -68,22 +44,16 @@ struct instr_t char *name; uint nprms; uint (*func)(acc_t *, acc_t *, acc_t *, - ulong *, ulong *, ulong *); + ulong *, ulong *); }; -bool eval_cond(uint cond); - void exec_instr(instr_t *in, acc_t *p1, acc_t *p2, - acc_t *p3, - bool lock, - bool rep); + acc_t *p3); void dump_instr(instr_t *in, acc_t *p1, acc_t *p2, - acc_t *p3, - bool lock, - bool rep); + acc_t *p3); diff --git a/vm/pc/dump.c b/vm/pc/dump.c index 6f94e28..00f538f 100644 --- a/vm/pc/dump.c +++ b/vm/pc/dump.c @@ -5,53 +5,15 @@ #define ABS(x) ((short)(x) < 0 ? -x : x) -static const char *cond_suffixes[] = -{ - "-", - "c", "o", "z", "s", "p", - "be", "l", "le", "axz", - "bxz", "cxz", - "?" -}; - static void dump_acc(acc_t *p); void dump_instr(instr_t *in, acc_t *p1, acc_t *p2, - acc_t *p3, - bool lock, - bool rep) + acc_t *p3) { - uint cond = ctx->cond; - trace("0x%lX:\t", ctx->cur_pc); - - if (lock) - trace("lock"); - - trace("%s", in->name); - - if (rep) - trace(".rep"); - - if (cond) - { - trace("."); - - if (cond & (1 << 4)) - trace("n"); - - assert((cond & ~(1 << 4)) <= sizeof(cond_suffixes)/sizeof(char *)); - - trace("%s", cond_suffixes[cond & ~(1 << 4)]); - } - - if (!rep && cond != ((1 << 4) | CD_CXZ)) - trace("\t\t"); - - else - trace("\t"); + trace("%s\t", in->name); if (p1) dump_acc(p1); diff --git a/vm/pc/except.c b/vm/pc/except.c index 5b9aafb..56c600a 100644 --- a/vm/pc/except.c +++ b/vm/pc/except.c @@ -75,7 +75,7 @@ void _except(int _code, char *fmt, ...) { if (ctx->dumpsw) { - trace("\nException %u - ", code); + trace("\n(Caught) Exception %u - ", code); va_start(ap, fmt); vprintf(fmt, ap); diff --git a/vm/pc/exec.c b/vm/pc/exec.c index 7ff6237..b968d5d 100644 --- a/vm/pc/exec.c +++ b/vm/pc/exec.c @@ -3,41 +3,6 @@ #include -#define rfx R(RFX) - -bool eval_cond(uint cond) -{ - bool neg = cond & (1 << 4); - bool ok; - - cond &= ~(1 << 4); - - switch (cond) - { - case CD_NONE: ok = 1; break; - - case CD_C: ok = rfx&CF; break; - case CD_O: ok = rfx&OF; break; - case CD_Z: ok = rfx&ZF; break; - case CD_S: ok = rfx&SF; break; - case CD_P: ok = rfx&PF; break; - - case CD_BE: ok = rfx&CF || rfx&ZF; break; - case CD_L: ok = !(rfx&SF) != !(rfx&OF); break; - case CD_LE: ok = rfx&ZF || (!(rfx&SF) != !(rfx&OF)); break; - - case CD_AXZ: ok = !R(RAX); break; - case CD_BXZ: ok = !R(RBX); break; - case CD_CXZ: ok = !R(RCX); break; - case CD_DXZ: ok = !R(RDX); break; - - default: - _except(E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond)); - } - - return neg ? !ok : !!ok; -} - #define OUTPUT(p, r) { \ if (p->type == A_REG) \ R(p->reg) = r; \ @@ -52,54 +17,26 @@ bool eval_cond(uint cond) void exec_instr(instr_t *in, acc_t *p1, acc_t *p2, - acc_t *p3, - bool lock, - bool rep) + acc_t *p3) { uint out; - ulong r1 = 0, r2 = 0, r3 = 0; + ulong r1 = 0, r2 = 0; // Global instruction counter ctx->ninstrs++; - // - // For REPs we evaluate the condition AFTER running the instruction, - // in a do ... while(cond) fashion - // - if (ctx->cond) - if (!rep && !eval_cond(ctx->cond)) - return; - if (ctx->dumpsw) - dump_instr(in, p1, p2, p3, lock, rep); + dump_instr(in, p1, p2, p3); -do_rep: - out = in->func(p1, p2, p3, &r1, &r2, &r3); + out = in->func(p1, p2, p3, &r1, &r2); if (out) { OUTPUT(p1, r1); - if (out >= 2) OUTPUT(p2, r2); - if (out >= 3) OUTPUT(p3, r3); + if (__builtin_expect(out == 2, 0)) + OUTPUT(p2, r2); + R(RZX) = 0; } - - if (rep) - { - // RCX remains untouched when condition fails - if (!eval_cond(ctx->cond)) - return; - - if (R(RCX) > 0) - R(RCX)--; - - if (R(RCX) == 0) - return; - - // Should we really count REP's in instruction count? - ctx->ninstrs++; - - goto do_rep; - } } diff --git a/vm/pc/mem.c b/vm/pc/mem.c index 2df44d3..b7779f0 100644 --- a/vm/pc/mem.c +++ b/vm/pc/mem.c @@ -106,7 +106,7 @@ static void writemem64(ulong val, ulong real, ulong addr) } #define GETREAL() \ - ulong real = addr2real(addr + R(CR2)) + ulong real = addr2real(addr + R(CR1)) //----------------------------------------------------------------------------// diff --git a/vm/pc/regs.c b/vm/pc/regs.c index 85181fc..0b8cc65 100644 --- a/vm/pc/regs.c +++ b/vm/pc/regs.c @@ -5,9 +5,6 @@ reg_t arch_r[] = { - { "zero", GPR }, { "cr0", SYS }, { "cr1", SYS }, { "cr2", SYS }, - { "rfx", GPR }, { "rip", GPR }, { "rbp", GPR }, { "rsp", GPR }, - { "rax", GPR }, { "rbx", GPR }, { "rcx", GPR }, { "rdx", GPR }, { "rsi", GPR }, { "rdi", GPR }, { "ax0", GPR }, { "ax1", GPR }, { "ax2", GPR }, { "ax3", GPR }, { "ax4", GPR }, { "ax5", GPR }, @@ -15,6 +12,9 @@ reg_t arch_r[] = { "r12", GPR }, { "r13", GPR }, { "r14", GPR }, { "r15", GPR }, { "r16", GPR }, { "r17", GPR }, { "r18", GPR }, { "r19", GPR }, { "r20", GPR }, { "grp", GPR }, { "trp", GPR }, { "srp", SYS }, + + { "tmp", GPR }, { "rad", GPR }, { "cr0", SYS }, { "cr1", SYS }, + { "rip", GPR }, { "rbp", GPR }, { "rsp", GPR }, { "zero", GPR }, }; static_assert(sizeof(arch_r)/sizeof(reg_t) == NREGS, ""); @@ -26,8 +26,8 @@ void dumpregs() TRACE("Current RFRAME index: #%lu", rfs_current_idx); TRACE("\n\nEnviron #1:"); - TRACE("\nrpc=0x%-16lX rip=0x%-16lX rfx=0x%-16lX", ctx->cur_pc, R(RIP), R(RFX)); - TRACE("\ncr0=0x%-16lX cr1=0x%-16lX cr2=0x%-16lX", R(CR0), R(CR1), R(CR2)); + TRACE("\nrpc=0x%-16lX rip=0x%-16lX", ctx->cur_pc, R(RIP)); + TRACE("\ncr0=0x%-16lX cr1=0x%-16lX", R(CR0), R(CR1)); TRACE("\n\nEnviron #2:"); TRACE("\nrsp=0x%-16lX rbp=0x%-16lX ins=0d%-16lu", R(RSP), R(RBP), ctx->ninstrs); diff --git a/vm/pc/regs.h b/vm/pc/regs.h index a7de68f..ea73bed 100644 --- a/vm/pc/regs.h +++ b/vm/pc/regs.h @@ -37,10 +37,10 @@ struct reg_t enum { - RZX, CR0, CR1, CR2, RFX, RIP, RBP, RSP, RAX, RBX, RCX, RDX, RSI, RDI, AX0, AX1, AX2, AX3, AX4, AX5, R12, R13, R14, R15, R16, R17, R18, R19, R20, GRP, TRP, SRP, + TMP, RAD, CR0, CR1, RIP, RBP, RSP, RZX, NREGS }; diff --git a/vm/pc/sym.c b/vm/pc/sym.c index 68babd2..e5f0987 100644 --- a/vm/pc/sym.c +++ b/vm/pc/sym.c @@ -18,9 +18,9 @@ int create_symtab(const char *name) return -1; } - while (fscanf(tab, "%s %lu\n", buf, &addr) > 0 && it < SYMTAB_LEN) + while (fscanf(tab, "%45s%*s %lu\n", buf, &addr) > 0 && it < SYMTAB_LEN) { - // log("SYM: '%.*s' '%lu'\n", SYMLEN_MAX, buf, addr); + //trace("SYM: '%.*s' '%lu'\n", SYMLEN_MAX, buf, addr); if (prev_addr > addr) { @@ -38,7 +38,6 @@ int create_symtab(const char *name) } fclose(tab); - return 0; } diff --git a/vm/pc/sym.h b/vm/pc/sym.h index 014a157..959bdf8 100644 --- a/vm/pc/sym.h +++ b/vm/pc/sym.h @@ -1,7 +1,7 @@ // The OS/K Team licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#define SYMLEN_MAX 32 +#define SYMLEN_MAX 46 #define SYMTAB_LEN 4096 typedef struct sym_t sym_t; @@ -9,7 +9,7 @@ typedef struct sym_t sym_t; struct sym_t { ulong addr; - char name[SYMLEN_MAX]; + char name[SYMLEN_MAX+1]; }; extern sym_t symtab[SYMTAB_LEN];