1
0
mirror of https://gitlab.os-k.eu/os-k-team/kvisc.git synced 2023-08-25 14:05:46 +02:00
This commit is contained in:
julianb0 2019-06-07 13:38:34 +02:00
parent 653a6e99c1
commit 504b41317e
No known key found for this signature in database
GPG Key ID: DDF8325C95299A62
6 changed files with 480 additions and 130 deletions

View File

@ -4,127 +4,449 @@
stop stop
nop nop
# #---------------------------------------------------------------------------#
# Logical instructions # Logical instructions #
# #---------------------------------------------------------------------------#
#
# Bitwise NOT operation
#
# $1 = NOT($1)
#
# Preserves all flags
#
!not rm !not rm
#
# Bitwise OR operation
#
# $1 = $1 OR $2
#
# Clears OF and CF
# Sets ZF and SF according to the result
#
!or rm rim !or rm rim
#
# Bitwise AND operation
#
# $1 = $1 AND $2
#
# Clears OF and CF
# Sets ZF and SF according to the result
#
!and rm rim !and rm rim
#
# Bitwise XOR operation
#
# $1 = $1 XOR $2
#
# Clears OF and CF
# Sets ZF and SF according to the result
#
!xor rm rim !xor rm rim
!shl rm rim !shl rm rim
!shr rm rim !shr rm rim
# #---------------------------------------------------------------------------#
# Unsigned arithmetic instructions # Arithmetic instructions #
# #---------------------------------------------------------------------------#
!neg rm #
!inc rm # Arithmetical SGN operation
!dec rm #
!add rm rim # IF ($1 == 0) THEN
!sub rm rim # $2 = 0
!mul rm rim # ELIF ($1 GT 0) THEN
!div rm rim # $2 = 1
!mod rm rim # ELSE
# $2 = LONG_MIN
# FI
#
# Treats $1 and $2 as signed values
# Sets ZF and SF according to the result
#
!sgn rm rim !sgn rm rim
# rdx = hi(rax * $0) #
# rax = lo(rax * $0) # Arithmetical NEG operation
#
# $1 = NOT($1) + 1
#
# Sets CF if $1 == 0; clears it otherwise
# Sets OF if $1 == $LONG_MIN; clears it otherwise
# Sets ZF and SF according to the result
#
!neg rm
#
# Arithmetical INC operation
#
# $1 = $1 + 1
#
# Preserves CF
# Sets OF if $1 == $LONG_MAX, clears it otherwise
# Sets ZF and SF according to the result
#
!inc rm
#
# Arithmetical DEC operation
#
# $1 = $1 - 1
#
# Preserves CF
# Sets OF if $1 == $LONG_MIN, clears it otherwise
# Sets ZF and SF according to the result
#
!dec rm
#
# Arithmetical ADD operation
#
# $1 = $1 + $2
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
!add rm rim
#
# Arithmetical SUB operation
#
# $1 = $1 - $2
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
!sub rm rim
#
# Arithmetical unsigned MUL operation
#
# $1 = LO($1 * $2)
#
# Sets CF and OF if HI($1 * $2) > 0, clears them otherwise
# Preserves ZF and SF
#
!mul rm rim
#
# Arithmetical unsigned DIV operation
#
# $1 = $1 DIV $2
#
# Preserves all flags
#
!div rm rim
#
# Arithmetical unsigned MOD operation
#
# $1 = $1 MOD $2
#
# Preserves all flags
#
!mod rm rim
#
# Arithmetical unsigned 128-bit MUL operation
#
# RDX = HI(RAX * $1)
# RAX = LO(RAX * $1)
#
# Sets CF and OF if HI($1 * $2) > 0, clears them otherwise
# Preserves ZF and SF
#
mul2 rim mul2 rim
# rdx = rax % $0 #
# rax = rax / $0 # Arithmetical unsigned combined DIV and MOD operations
#
# RDX = (RAX MOD $1)
# RAX = (RAX DIV $1)
#
# Preserves all flags
#
div2 rim div2 rim
# #---------------------------------------------------------------------------#
# Comparison instruction # Comparison instructions #
# #---------------------------------------------------------------------------#
cmp rim rim
#cmpb rim rim
#cmpw rim rim
#cmpl rim rim
#cmpt rim rim
#
# TEST Comparaison instruction
#
# $1 AND $2
#
# Clears OF and CF
# Sets ZF and SF according to the result
#
test rim rim test rim rim
#testb rim rim
#testw rim rim
#testl rim rim
#testt rim rim
# #
# Jump instructions # CMP Comparaison instruction
# #
# $1 - $2
#
# Sets CF if unsigned integer overflow occur, clears it otherwise
# Sets OF is signed integer overflow occur, clears it otherwise
# Sets ZF and SF according to the result
#
cmp rim rim
#---------------------------------------------------------------------------#
# Jump instructions #
#---------------------------------------------------------------------------#
#
# Unconditional jump (JMP) instruction
#
# RIP = CR1 + $1
#
!j ri !j ri
!jmp ri !jmp ri
#
# RCX-dependent jump (LOOP) instruction
#
# IF (RCX > 0) THEN
# RCX = RCX - 1
# RIP = CR1 + $1
# FI
#
!loop ri !loop ri
# #---------------------------------------------------------------------------#
# Movement instructions # Movement instructions #
# #---------------------------------------------------------------------------#
#
# Load Effective Address (LEA) instruction
#
# $1 = ADDR($2)
#
# For instance:
# LEA RAX, [RBX + RCX + 4]
# will result in:
# RAX = RBX + RCX + 4
#
# Preserves all flags
#
!lea rm m !lea rm m
#
# Movement (MOV) instruction
#
# $1 = $2
#
!mov rm rim !mov rm rim
#
# Exchange (XCHG) instruction
#
# $_ = $1
# $1 = $2
# $2 = $_
#
!xchg rm rim !xchg rm rim
#
# Compare-and-exchange (CMPXCHG) instruction
#
# IF ($1 == RAX) THEN
# $1 = $2
# ZF = 1
# ELSE
# RAX = $1
# ZF = 0
# FI
#
# Preserves CF, OF and SF
#
cmpxchg rm rim cmpxchg rm rim
movb rm rim # Undocumented
movw rm rim # movb rm rim
movl rm rim # movw rm rim
movt rm rim # movl rm rim
# movt rm rim
#---------------------------------------------------------------------------#
# Stack manipulation instructions #
#---------------------------------------------------------------------------#
# #
# Stack manipulation instructions # PUSH value onto stack
#
# RSP = RSP - 8
# *RSP = $1
#
# Throws:
# #STA if RBP MOD 8 > 0
# #STA if RSP MOD 8 > 0
# #STU if RSP > RBP
# #
!push rim !push rim
!call rim
#
# POP value from stack
#
# $1 = *RSP
# RSP = RSP + 8
#
# Throws:
# #STA if RBP MOD 8 > 0
# #STA if RSP MOD 8 > 0
# #STU if RSP >= RBP
#
!pop rm !pop rm
#
# Unconditional jump with possible return (CALL)
#
# PUSH(RIP)
# JMP(RIP)
#
# Throws:
# See PUSH and JMP
#
!call rim
#
# Return to caller (RET)
#
# POP(RIP)
#
# Throws:
# See POP
#
!ret !ret
# push rbp #
# mov rbp, rsp # Make new stack frame (ENTER)
#
# PUSH(RBP)
# RBP = RSP
#
# Throws:
# See PUSH
#
enter enter
# add rsp, 8 #
# mov rbp, [rsp] # Leave stack frame (LEAVE)
#
# RBP = *RSP
# RSP = RSP + 8
#
!leave !leave
#---------------------------------------------------------------------------#
# Supervisor only instructions #
#---------------------------------------------------------------------------#
pushf pushf
popf popf
# #
# Supervisor only instructions # Clear or set interrupt flag (CLI/STI)
#
# Throws:
# #SYS if not in supervisor mode
# #
cli cli
sti sti
#
# Call an architecture-reserved function slot of device (DEVCTL)
#
# See dv/DEVAPI
#
devctl rim rim devctl rim rim
#
# Call a device-defined function slot of device (IOCALL)
#
# See dv/DEVAPI
#
iocall rim rim iocall rim rim
# #---------------------------------------------------------------------------#
# Misc. instructions # Misc. instructions #
# #---------------------------------------------------------------------------#
# Clear rax...rsi #
# Get code/date offset (GCO/GCD)
#
# $1 = CR1 (GCO)
# $1 = CR2 (GCD)
#
gco rm
gcd rm
#
# Clear base volatile registers (CLR)
#
# RAX = RBX = RCX = RDX = 0
# RSX = RBI = RDI = RSI = 0
#
clr clr
# Clear ax0...ax7 #
# Clear argument registers (CLA)
#
# AX0 = AX1 = AX2 = AX3 = 0
# AX4 = AX5 = AX6 = AX7 = 0
#
cla cla
# Clear nx0...nx7
cln
# Print a character on the screen
prn rim
# #
# Debugging instructions # Clear base non-volatile registers (CLN)
#
# NX0 = NX1 = NX2 = NX3 = 0
# NX4 = NX5 = NX6 = NX7 = 0
#
cln
#
# Send a character to standard output
#
# Throws:
# #PRN if DV text mode enabled
# #PRN if graphic mode enabled
#
prn rim
#---------------------------------------------------------------------------#
# Debugging instructions #
#---------------------------------------------------------------------------#
#
# Breakpoint instruction (BREAK)
#
# (cause register dump on standard error)
# (wait for user input before proceeeding)
# #
!break !break
#
# Step-by-step execution (STEP)
#
# IF $1 == 0 THEN
# (disable step-by-step execution)
# ELSE
# (enable step-by-step execution)
# FI
#
step rim step rim
#---------------------------------------------------------------------------#

View File

@ -4,6 +4,7 @@
#include <in/instrs.h> #include <in/instrs.h>
IMPL_COND(sgn); IMPL_COND(sgn);
IMPL_COND(neg);
IMPL_COND(inc); IMPL_COND(inc);
IMPL_COND(dec); IMPL_COND(dec);
IMPL_COND(add); IMPL_COND(add);
@ -16,6 +17,29 @@ IMPL_COND(div2);
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
IMPL_START_2(sgn)
{
v1 = (long)v2 < 0 ? (ulong)-1L : 1;
}
IMPL_OUT_ZSF;
IMPL_START_1(neg)
{
if (v1 == 0) flg |= CF;
else {
flg &= ~CF;
if (v1 == LONG_MIN) flg |= OF;
else flg &= ~OF;
}
v1 = ~v1 + 1;
}
IMPL_OUT_ZSF;
//--------------------------------------------------------------------------
IMPL_START_1(inc) IMPL_START_1(inc)
{ {
if (v1 == LONG_MAX) flg |= OF; if (v1 == LONG_MAX) flg |= OF;
@ -83,35 +107,61 @@ IMPL_END;
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
//
// www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
//
static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
{
ulong u1 = (u & 0xffffffff);
ulong v1 = (v & 0xffffffff);
ulong t = (u1 * v1);
ulong w3 = (t & 0xffffffff);
ulong k = (t >> 32);
u >>= 32;
t = (u * v1) + k;
k = (t & 0xffffffff);
ulong w1 = (t >> 32);
v >>= 32;
t = (u1 * v) + k;
k = (t >> 32);
*hi = (u * v) + w1 + k;
*lo = (t << 32) + w3;
}
IMPL_START_2(mul) IMPL_START_2(mul)
{ {
v1 *= v2; ulong hi;
multiply(v1, v2, &hi, &v1);
if (hi > 0) {
flg |= CF;
flg |= OF;
}
else {
flg &= ~CF;
flg &= ~OF;
}
} }
IMPL_OUT; IMPL_OUT;
IMPL_START_1(mul2) IMPL_START_1(mul2)
{ {
// Adapted from www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring multiply(rax, v1, &rdx, &rax);
ulong v2 = v1;
v1 = rax;
ulong u1 = (v1 & 0xffffffff); if (rdx > 0) {
ulong u2 = (v2 & 0xffffffff); flg |= CF;
ulong t = (u1 * u2); flg |= OF;
ulong w3 = (t & 0xffffffff); }
ulong k = (t >> 32);
v1 >>= 32; else {
t = (v1 * u2) + k; flg &= ~CF;
k = (t & 0xffffffff); flg &= ~OF;
ulong w1 = (t >> 32); }
v2 >>= 32;
t = (u1 * v2) + k;
k = (t >> 32);
rdx = (v1 * v2) + w1 + k;
rax = (t << 32) + w3;
} }
IMPL_END; IMPL_END;
@ -136,36 +186,3 @@ IMPL_START_1(div2)
} }
IMPL_END; IMPL_END;
//--------------------------------------------------------------------------
IMPL_START_2(sgn)
{
if (v2 == 0) v1 = 0;
else if ((long)v2 > 0) {
flg &= ~CF;
v1 = 1;
}
else {
flg |= CF;
v1 = (ulong)-1L;
}
}
IMPL_OUT_ZSF;
IMPL_START_1(neg)
{
if (v1 == 0) flg |= CF;
else {
flg &= ~CF;
if (v1 == LONG_MIN) flg |= OF;
else flg &= ~OF;
}
v1 = ~v1 + 1;
}
IMPL_OUT_ZSF;

View File

@ -1,6 +1,8 @@
// The OS/K Team licenses this file to you under the MIT license. // The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
#define PARITY(v) __builtin_parity(v)
#define SET_ZF(v) \ #define SET_ZF(v) \
flg = ((v) == 0 ? (flg|ZF) : (flg&~ZF)) flg = ((v) == 0 ? (flg|ZF) : (flg&~ZF))
@ -8,7 +10,7 @@
flg = ((long)(v) < 0 ? (flg|SF) : (flg&~SF)) flg = ((long)(v) < 0 ? (flg|SF) : (flg&~SF))
#define SET_PF(v) \ #define SET_PF(v) \
flg = (__builtin_parity(v) == 1 ? (flg|PF) : (flg&~PF)) flg = (PARITY(v) == 1 ? (flg|PF) : (flg&~PF))
#define SET_ZSF(v) \ #define SET_ZSF(v) \
SET_ZF(v); \ SET_ZF(v); \

View File

@ -78,10 +78,10 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
#define CHK_STACK(op) \ #define CHK_STACK(op) \
if (rsp % 8 > 0 || rbp % 8 > 0) { \ if (rsp % 8 > 0 || rbp % 8 > 0) { \
_except(ctx, E_STK, "Misaligned stack REGS"); \ _except(ctx, E_STA, "Misaligned stack REGS"); \
} \ } \
if (rbp op rsp) { \ if (rbp op rsp) { \
_except(ctx, E_STK, "RSP above RBP"); \ _except(ctx, E_STU, "Stack underflow"); \
} }
// //
@ -89,12 +89,12 @@ void i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2) \
// //
#define PUSH(v) \ #define PUSH(v) \
writemem64(ctx, v, rsp); \ rsp -= 8; \
rsp -= 8; writemem64(ctx, v, rsp);
#define POP(v) \ #define POP(v) \
rsp += 8; \ v = readmem64(ctx, rsp); \
v = readmem64(ctx, rsp); rsp += 8;
#define JUMP(v) \ #define JUMP(v) \
rip = v + cr1 rip = v + cr1

View File

@ -5,10 +5,6 @@
IMPL_COND(lea); IMPL_COND(lea);
IMPL_COND(mov); IMPL_COND(mov);
IMPL_COND(movb);
IMPL_COND(movw);
IMPL_COND(movl);
IMPL_COND(movt);
IMPL_COND(xchg); IMPL_COND(xchg);
IMPL_COND(cmpxchg); IMPL_COND(cmpxchg);
@ -57,6 +53,11 @@ IMPL_START_2(movt)
} }
IMPL_OUT; IMPL_OUT;
IMPL_COND(movb);
IMPL_COND(movw);
IMPL_COND(movl);
IMPL_COND(movt);
IMPL_START_2(xchg) IMPL_START_2(xchg)
{ {
ulong t = v1; ulong t = v1;
@ -77,12 +78,6 @@ IMPL_START_1(lea)
} }
IMPL_OUT; IMPL_OUT;
IMPL_START_1(gcs)
{
v1 = cr1;
}
IMPL_OUT;
IMPL_START_2(cmpxchg) IMPL_START_2(cmpxchg)
{ {
if (rax == v1) { if (rax == v1) {
@ -97,3 +92,16 @@ IMPL_START_2(cmpxchg)
} }
IMPL_OUT; IMPL_OUT;
IMPL_START_1(gco)
{
v1 = cr1;
}
IMPL_OUT;
IMPL_START_1(gcd)
{
v1 = cr2;
}
IMPL_OUT;

View File

@ -134,7 +134,8 @@ enum
E_ACC, // Invalid access E_ACC, // Invalid access
E_SYS, // Supervisor only E_SYS, // Supervisor only
E_ALI, // Alignment error E_ALI, // Alignment error
E_STK, // Stack error E_STA, // Stack misalignment
E_STU, // Stack underflow
NEXCPTS NEXCPTS
}; };