mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
sign extension
This commit is contained in:
parent
b6f7b3ec16
commit
434e3ff63d
15
ka/main.k
15
ka/main.k
@ -5,6 +5,21 @@
|
|||||||
; Main function
|
; Main function
|
||||||
;
|
;
|
||||||
main:
|
main:
|
||||||
|
enter 1
|
||||||
|
|
||||||
|
mov q[rsp], 0xFABC1234CCCCDDDD
|
||||||
|
|
||||||
|
mov rax, b[rsp]
|
||||||
|
mov rbx, w[rsp]
|
||||||
|
mov rcx, l[rsp]
|
||||||
|
mov rdx, q[rsp]
|
||||||
|
|
||||||
|
movzx rsx, b[rsp]
|
||||||
|
movzx rbi, w[rsp]
|
||||||
|
movzx rdi, l[rsp]
|
||||||
|
movzx rsi, q[rsp]
|
||||||
|
|
||||||
|
leave
|
||||||
ret
|
ret
|
||||||
|
|
||||||
itoa_test:
|
itoa_test:
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
//
|
//
|
||||||
dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2)
|
dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2)
|
||||||
{
|
{
|
||||||
|
|
||||||
dev_t *dev = devget(ctx, v1);
|
dev_t *dev = devget(ctx, v1);
|
||||||
|
|
||||||
if (!dev)
|
if (!dev)
|
||||||
@ -33,10 +32,10 @@ dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2)
|
|||||||
void copystr(ctx_t *ctx, ulong addr, ulong maxn, char *str)
|
void copystr(ctx_t *ctx, ulong addr, ulong maxn, char *str)
|
||||||
{
|
{
|
||||||
for (; *str && maxn > 0; str++, addr++, maxn--) {
|
for (; *str && maxn > 0; str++, addr++, maxn--) {
|
||||||
writemem8(ctx, *str, addr);
|
writemem(ctx, *str, addr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
writemem8(ctx, 0, addr);
|
writemem(ctx, 0, addr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPL_START_2(devctl)
|
IMPL_START_2(devctl)
|
||||||
|
107
vm/in/INSTRS
107
vm/in/INSTRS
@ -273,6 +273,13 @@ lea rm m
|
|||||||
#
|
#
|
||||||
mov rm rim
|
mov rm rim
|
||||||
|
|
||||||
|
#
|
||||||
|
# Movement with zero-extension (MOVZX) instruction
|
||||||
|
#
|
||||||
|
# $1 = ZeroExtend($2)
|
||||||
|
#
|
||||||
|
movzx rm m
|
||||||
|
|
||||||
#
|
#
|
||||||
# Exchange (XCHG) instruction
|
# Exchange (XCHG) instruction
|
||||||
#
|
#
|
||||||
@ -297,12 +304,6 @@ xchg rm rim
|
|||||||
#
|
#
|
||||||
cmpxchg rm rim
|
cmpxchg rm rim
|
||||||
|
|
||||||
# Undocumented
|
|
||||||
# movb rm rim
|
|
||||||
# movw rm rim
|
|
||||||
# movl rm rim
|
|
||||||
# movt rm rim
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Stack manipulation instructions #
|
# Stack manipulation instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
@ -375,6 +376,10 @@ enter i
|
|||||||
#
|
#
|
||||||
leave
|
leave
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# String manipulation instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Supervisor only instructions #
|
# Supervisor only instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
@ -382,15 +387,6 @@ leave
|
|||||||
pushf
|
pushf
|
||||||
popf
|
popf
|
||||||
|
|
||||||
#
|
|
||||||
# Clear or set interrupt flag (CLI/STI)
|
|
||||||
#
|
|
||||||
# Throws:
|
|
||||||
# #SYS if not in supervisor mode
|
|
||||||
#
|
|
||||||
cli
|
|
||||||
sti
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Call an architecture-reserved function slot of device (DEVCTL)
|
# Call an architecture-reserved function slot of device (DEVCTL)
|
||||||
#
|
#
|
||||||
@ -405,6 +401,32 @@ devctl rim rim
|
|||||||
#
|
#
|
||||||
iocall rim rim
|
iocall rim rim
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
# Flag manipulation instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clear or set interrupt flag (CLI/STI)
|
||||||
|
#
|
||||||
|
# Throws:
|
||||||
|
# #SYS if not in supervisor mode
|
||||||
|
#
|
||||||
|
cli
|
||||||
|
sti
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clear or set direction flag (CLD/STD)
|
||||||
|
#
|
||||||
|
cld
|
||||||
|
std
|
||||||
|
|
||||||
|
#
|
||||||
|
# Complement, clear or set carry flag (CMC/CLC/STC)
|
||||||
|
#
|
||||||
|
cmc
|
||||||
|
clc
|
||||||
|
stc
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Misc. instructions #
|
# Misc. instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
@ -422,7 +444,7 @@ iocall rim rim
|
|||||||
nop
|
nop
|
||||||
|
|
||||||
#
|
#
|
||||||
# Get code/date offset (GCO/GCD)
|
# Get code/data offset (GCO/GCD)
|
||||||
#
|
#
|
||||||
# $1 = CR1 (GCO)
|
# $1 = CR1 (GCO)
|
||||||
# $1 = CR2 (GCD)
|
# $1 = CR2 (GCD)
|
||||||
@ -430,31 +452,6 @@ nop
|
|||||||
gco rm
|
gco rm
|
||||||
gcd rm
|
gcd rm
|
||||||
|
|
||||||
#
|
|
||||||
# Clear base volatile registers (CLR)
|
|
||||||
#
|
|
||||||
# RAX = RBX = RCX = RDX = 0
|
|
||||||
# RSX = RBI = RDI = RSI = 0
|
|
||||||
#
|
|
||||||
clr
|
|
||||||
|
|
||||||
#
|
|
||||||
# Clear argument registers (CLA)
|
|
||||||
#
|
|
||||||
# AX0 = AX1 = AX2 = AX3 = 0
|
|
||||||
# AX4 = AX5 = AX6 = AX7 = 0
|
|
||||||
#
|
|
||||||
cla
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Clear base non-volatile registers (CLN)
|
|
||||||
#
|
|
||||||
# NX0 = NX1 = NX2 = NX3 = 0
|
|
||||||
# NX4 = NX5 = NX6 = NX7 = 0
|
|
||||||
#
|
|
||||||
cln
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Send a character to standard output (PRN)
|
# Send a character to standard output (PRN)
|
||||||
#
|
#
|
||||||
@ -488,4 +485,32 @@ break
|
|||||||
step rim
|
step rim
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
|
# Clean-up misc. instructions #
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clear base volatile registers (CLR)
|
||||||
|
#
|
||||||
|
# RAX = RBX = RCX = RDX = 0
|
||||||
|
# RSX = RBI = RDI = RSI = 0
|
||||||
|
#
|
||||||
|
clr
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clear argument registers (CLA)
|
||||||
|
#
|
||||||
|
# AX0 = AX1 = AX2 = AX3 = 0
|
||||||
|
# AX4 = AX5 = AX6 = AX7 = 0
|
||||||
|
#
|
||||||
|
cla
|
||||||
|
|
||||||
|
#
|
||||||
|
# Clear base non-volatile registers (CLN)
|
||||||
|
#
|
||||||
|
# NX0 = NX1 = NX2 = NX3 = 0
|
||||||
|
# NX4 = NX5 = NX6 = NX7 = 0
|
||||||
|
#
|
||||||
|
cln
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
@ -11,27 +11,53 @@ IMPL_START_0(nop)
|
|||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
//
|
//----------------------------------------------------------------------------//
|
||||||
// Misc. instructions
|
|
||||||
//
|
|
||||||
|
|
||||||
IMPL_START_1(prn)
|
IMPL_START_1(prn)
|
||||||
{
|
{
|
||||||
if (p1->mlen > 1) {
|
if (p1->mlen > 1) {
|
||||||
log("prn warning: large access size\n");
|
log("prn warning: large access size\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (!(v1 >= ' ' && v1 < 128) && v1 != '\t' && v1 != '\n') {
|
|
||||||
log("prn on invalid character: %ld\n", v1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
putchar((int)v1);
|
putchar((int)v1);
|
||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_0(cld)
|
||||||
|
{
|
||||||
|
flg &= ~DF;
|
||||||
|
}
|
||||||
|
IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(std)
|
||||||
|
{
|
||||||
|
flg |= DF;
|
||||||
|
}
|
||||||
|
IMPL_END;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
IMPL_START_0(cmc)
|
||||||
|
{
|
||||||
|
flg = (flg&CF ? flg&~CF : flg|CF);
|
||||||
|
}
|
||||||
|
IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(clc)
|
||||||
|
{
|
||||||
|
flg &= ~CF;
|
||||||
|
}
|
||||||
|
IMPL_END;
|
||||||
|
|
||||||
|
IMPL_START_0(stc)
|
||||||
|
{
|
||||||
|
flg |= CF;
|
||||||
|
}
|
||||||
|
IMPL_END;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_0(clr)
|
IMPL_START_0(clr)
|
||||||
{
|
{
|
||||||
rax = rbx = rcx = rdx = 0;
|
rax = rbx = rcx = rdx = 0;
|
||||||
@ -53,3 +79,5 @@ IMPL_START_0(cln)
|
|||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <in/flags.h>
|
#include <in/flags.h>
|
||||||
#include <in/arch_i.h>
|
#include <in/arch_i.h>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#define GETV(v, p) \
|
#define GETV(v, p) \
|
||||||
ulong v; \
|
ulong v; \
|
||||||
assert(p); \
|
assert(p); \
|
||||||
@ -13,6 +15,14 @@
|
|||||||
v = readmem(ctx, p->addr, p->mlen); \
|
v = readmem(ctx, p->addr, p->mlen); \
|
||||||
else v = p->val
|
else v = p->val
|
||||||
|
|
||||||
|
#define GETVZX(v, p) \
|
||||||
|
ulong v; \
|
||||||
|
assert(p); \
|
||||||
|
if (ACC_FMT_IS_MEM(p->type)) \
|
||||||
|
v = readmemzx(ctx, p->addr, p->mlen); \
|
||||||
|
else v = p->val
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#define IMPL_START_0(name) \
|
#define IMPL_START_0(name) \
|
||||||
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \
|
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \
|
||||||
@ -48,9 +58,7 @@ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \
|
|||||||
return 0; \
|
return 0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//----------------------------------------------------------------------------//
|
||||||
// Consistency checks
|
|
||||||
//
|
|
||||||
|
|
||||||
#define CHK_SUPERV() \
|
#define CHK_SUPERV() \
|
||||||
do { \
|
do { \
|
||||||
@ -67,18 +75,18 @@ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *r1, ulong *r2) \
|
|||||||
_except(ctx, E_STU, "Stack underflow"); \
|
_except(ctx, E_STU, "Stack underflow"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//----------------------------------------------------------------------------//
|
||||||
// Common operations
|
|
||||||
//
|
|
||||||
|
|
||||||
#define PUSH(v) \
|
#define PUSH(v) \
|
||||||
rsp -= 8; \
|
rsp -= 8; \
|
||||||
writemem64(ctx, v, rsp);
|
writemem(ctx, v, rsp, 8);
|
||||||
|
|
||||||
#define POP(v) \
|
#define POP(v) \
|
||||||
v = readmem64(ctx, rsp); \
|
v = readmem(ctx, rsp, 8); \
|
||||||
rsp += 8;
|
rsp += 8;
|
||||||
|
|
||||||
#define JUMP(v) \
|
#define JUMP(v) \
|
||||||
rip = v + cr1
|
rip = v + cr1
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
44
vm/in/mov.c
44
vm/in/mov.c
@ -3,9 +3,13 @@
|
|||||||
|
|
||||||
#include <in/instrs.h>
|
#include <in/instrs.h>
|
||||||
|
|
||||||
//
|
IMPL_START_1(lea)
|
||||||
// Movement instructions
|
{
|
||||||
//
|
v1 = p2->addr;
|
||||||
|
}
|
||||||
|
IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_2(mov)
|
IMPL_START_2(mov)
|
||||||
{
|
{
|
||||||
@ -13,33 +17,14 @@ IMPL_START_2(mov)
|
|||||||
}
|
}
|
||||||
IMPL_OUT;
|
IMPL_OUT;
|
||||||
|
|
||||||
IMPL_START_2(movb)
|
IMPL_START_1(movzx)
|
||||||
{
|
{
|
||||||
v1 = (v1 & 0xFFFFFFFFFFFFFF00)
|
GETVZX(v2, p2);
|
||||||
| (v2 & 0x00000000000000FF);
|
v1 = v2;
|
||||||
}
|
}
|
||||||
IMPL_OUT;
|
IMPL_OUT;
|
||||||
|
|
||||||
IMPL_START_2(movw)
|
//----------------------------------------------------------------------------//
|
||||||
{
|
|
||||||
v1 = (v1 & 0xFFFFFFFFFFFF0000)
|
|
||||||
| (v2 & 0x000000000000FFFF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(movl)
|
|
||||||
{
|
|
||||||
v1 = (v1 & 0xFFFFFFFF00000000)
|
|
||||||
| (v2 & 0x00000000FFFFFFFF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(movt)
|
|
||||||
{
|
|
||||||
v1 = (v1 & 0xFFFF000000000000)
|
|
||||||
| (v2 & 0x0000FFFFFFFFFFFF);
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(xchg)
|
IMPL_START_2(xchg)
|
||||||
{
|
{
|
||||||
@ -49,11 +34,6 @@ IMPL_START_2(xchg)
|
|||||||
}
|
}
|
||||||
IMPL_OUT_2;
|
IMPL_OUT_2;
|
||||||
|
|
||||||
IMPL_START_1(lea)
|
|
||||||
{
|
|
||||||
v1 = p2->addr;
|
|
||||||
}
|
|
||||||
IMPL_OUT;
|
|
||||||
|
|
||||||
IMPL_START_2(cmpxchg)
|
IMPL_START_2(cmpxchg)
|
||||||
{
|
{
|
||||||
@ -69,6 +49,8 @@ IMPL_START_2(cmpxchg)
|
|||||||
}
|
}
|
||||||
IMPL_OUT;
|
IMPL_OUT;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
IMPL_START_1(gco)
|
IMPL_START_1(gco)
|
||||||
{
|
{
|
||||||
v1 = cr1;
|
v1 = cr1;
|
||||||
|
12
vm/pc/arch.h
12
vm/pc/arch.h
@ -92,18 +92,12 @@ void decode(ctx_t *ctx);
|
|||||||
// Address of boot firmware stack
|
// Address of boot firmware stack
|
||||||
#define FWSTACK (MEMOFF * 2) // 2MB
|
#define FWSTACK (MEMOFF * 2) // 2MB
|
||||||
|
|
||||||
ulong readmem8(ctx_t *, ulong addr);
|
|
||||||
ulong readmem16(ctx_t *, ulong addr);
|
|
||||||
ulong readmem32(ctx_t *, ulong addr);
|
|
||||||
ulong readmem64(ctx_t *, ulong addr);
|
|
||||||
ulong readmem(ctx_t *c, ulong addr, uint len);
|
ulong readmem(ctx_t *c, ulong addr, uint len);
|
||||||
|
|
||||||
void writemem8(ctx_t *, ulong val, ulong addr);
|
|
||||||
void writemem16(ctx_t *, ulong val, ulong addr);
|
|
||||||
void writemem32(ctx_t *, ulong val, ulong addr);
|
|
||||||
void writemem64(ctx_t *, ulong val, ulong addr);
|
|
||||||
void writemem(ctx_t *, ulong val, ulong addr, uint len);
|
void writemem(ctx_t *, ulong val, ulong addr, uint len);
|
||||||
|
|
||||||
|
ulong readmemzx(ctx_t *c, ulong addr, uint len);
|
||||||
|
void writememzx(ctx_t *, ulong val, ulong addr, uint len);
|
||||||
|
|
||||||
#include <pc/regs.h>
|
#include <pc/regs.h>
|
||||||
#include <pc/decd.h>
|
#include <pc/decd.h>
|
||||||
#include <in/arch_i.h>
|
#include <in/arch_i.h>
|
||||||
|
168
vm/pc/mem.c
168
vm/pc/mem.c
@ -3,33 +3,7 @@
|
|||||||
|
|
||||||
#include <pc/arch.h>
|
#include <pc/arch.h>
|
||||||
|
|
||||||
ulong readmem(ctx_t *ctx, ulong addr, uint len)
|
//----------------------------------------------------------------------------//
|
||||||
{
|
|
||||||
switch (len) {
|
|
||||||
case 1: return readmem8(ctx, addr); break;
|
|
||||||
case 2: return readmem16(ctx, addr); break;
|
|
||||||
case 4: return readmem32(ctx, addr); break;
|
|
||||||
case 8: return readmem64(ctx, addr); break;
|
|
||||||
default: log("readmem() bad length!\n"); abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
|
||||||
{
|
|
||||||
switch (len) {
|
|
||||||
case 1: writemem8(ctx, val, addr); break;
|
|
||||||
case 2: writemem16(ctx, val, addr); break;
|
|
||||||
case 4: writemem32(ctx, val, addr); break;
|
|
||||||
case 8: writemem64(ctx, val, addr); break;
|
|
||||||
default: log("writemem() bad length!\n"); abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHK_RANGE() \
|
|
||||||
if (addr < MEMOFF || real >= MEMSIZE) { \
|
|
||||||
_except(ctx, E_ACC, \
|
|
||||||
"Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHK_ALIGN(type) \
|
#define CHK_ALIGN(type) \
|
||||||
if (addr % alignof(type) > 0) { \
|
if (addr % alignof(type) > 0) { \
|
||||||
@ -38,32 +12,23 @@ void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
|||||||
addr, real, alignof(type)); \
|
addr, real, alignof(type)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GETREAL() \
|
//----------------------------------------------------------------------------//
|
||||||
addr += cr2; \
|
|
||||||
ulong real = addr2real(addr)
|
|
||||||
|
|
||||||
ulong readmem8(ctx_t *ctx, ulong addr)
|
static ulong readmem8(ctx_t *ctx, ulong real, ulong addr)
|
||||||
{
|
{
|
||||||
GETREAL();
|
|
||||||
CHK_RANGE();
|
|
||||||
|
|
||||||
if (addr % 2 == 0) return (ulong)ctx->mp[real] & 0xFF;
|
if (addr % 2 == 0) return (ulong)ctx->mp[real] & 0xFF;
|
||||||
else return ((ulong)ctx->mp[real] & 0xFF00) >> 8;
|
else return ((ulong)ctx->mp[real] & 0xFF00) >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong readmem16(ctx_t *ctx, ulong addr)
|
static ulong readmem16(ctx_t *ctx, ulong real, ulong addr)
|
||||||
{
|
{
|
||||||
GETREAL();
|
|
||||||
CHK_RANGE();
|
|
||||||
CHK_ALIGN(ushort);
|
CHK_ALIGN(ushort);
|
||||||
|
|
||||||
return (ulong)ctx->mp[real];
|
return (ulong)ctx->mp[real];
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong readmem32(ctx_t *ctx, ulong addr)
|
static ulong readmem32(ctx_t *ctx, ulong real, ulong addr)
|
||||||
{
|
{
|
||||||
GETREAL();
|
|
||||||
CHK_RANGE();
|
|
||||||
CHK_ALIGN(uint);
|
CHK_ALIGN(uint);
|
||||||
|
|
||||||
ulong val = ctx->mp[real++];
|
ulong val = ctx->mp[real++];
|
||||||
@ -72,10 +37,8 @@ ulong readmem32(ctx_t *ctx, ulong addr)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong readmem64(ctx_t *ctx, ulong addr)
|
static ulong readmem64(ctx_t *ctx, ulong real, ulong addr)
|
||||||
{
|
{
|
||||||
GETREAL();
|
|
||||||
CHK_RANGE();
|
|
||||||
CHK_ALIGN(ulong);
|
CHK_ALIGN(ulong);
|
||||||
|
|
||||||
ulong val = (ulong)ctx->mp[real++];
|
ulong val = (ulong)ctx->mp[real++];
|
||||||
@ -86,11 +49,10 @@ ulong readmem64(ctx_t *ctx, ulong addr)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writemem8(ctx_t *ctx, ulong val, ulong addr)
|
//----------------------------------------------------------------------------//
|
||||||
{
|
|
||||||
GETREAL();
|
|
||||||
CHK_RANGE();
|
|
||||||
|
|
||||||
|
static void writemem8(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||||
|
{
|
||||||
ushort v = ctx->mp[real];
|
ushort v = ctx->mp[real];
|
||||||
|
|
||||||
if (!(addr % 2)) {
|
if (!(addr % 2)) {
|
||||||
@ -102,29 +64,23 @@ void writemem8(ctx_t *ctx, ulong val, ulong addr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writemem16(ctx_t *ctx, ulong val, ulong addr)
|
static void writemem16(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||||
{
|
{
|
||||||
GETREAL();
|
|
||||||
CHK_RANGE();
|
|
||||||
CHK_ALIGN(ushort);
|
CHK_ALIGN(ushort);
|
||||||
|
|
||||||
ctx->mp[real] = val & 0xFFFF;
|
ctx->mp[real] = val & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writemem32(ctx_t *ctx, ulong val, ulong addr)
|
static void writemem32(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||||
{
|
{
|
||||||
GETREAL();
|
|
||||||
CHK_RANGE();
|
|
||||||
CHK_ALIGN(uint);
|
CHK_ALIGN(uint);
|
||||||
|
|
||||||
ctx->mp[real++] = val & 0xFFFF;
|
ctx->mp[real++] = val & 0xFFFF;
|
||||||
ctx->mp[real] = (val >> 16) & 0xFFFF;
|
ctx->mp[real] = (val >> 16) & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writemem64(ctx_t *ctx, ulong val, ulong addr)
|
static void writemem64(ctx_t *ctx, ulong val, ulong real, ulong addr)
|
||||||
{
|
{
|
||||||
GETREAL();
|
|
||||||
CHK_RANGE();
|
|
||||||
CHK_ALIGN(ulong);
|
CHK_ALIGN(ulong);
|
||||||
|
|
||||||
ctx->mp[real++] = val;
|
ctx->mp[real++] = val;
|
||||||
@ -133,3 +89,103 @@ void writemem64(ctx_t *ctx, ulong val, ulong addr)
|
|||||||
ctx->mp[real] = (val >> 48) & 0xFFFF;
|
ctx->mp[real] = (val >> 48) & 0xFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#define CHK_RANGE() \
|
||||||
|
if (addr < MEMOFF || real >= MEMSIZE) { \
|
||||||
|
_except(ctx, E_ACC, \
|
||||||
|
"Invalid MEM access: 0x%012lX (0x%012lX)", addr, real); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GETREAL() \
|
||||||
|
addr += cr2; \
|
||||||
|
ulong real = addr2real(addr)
|
||||||
|
|
||||||
|
#define SIGN_EXTEND(val, mask) \
|
||||||
|
(val & ((mask + 1) >> 1) \
|
||||||
|
? (val | ~mask) \
|
||||||
|
: val)
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
ulong readmem(ctx_t *ctx, ulong addr, uint len)
|
||||||
|
{
|
||||||
|
GETREAL();
|
||||||
|
CHK_RANGE();
|
||||||
|
|
||||||
|
ulong val;
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
|
case 1:
|
||||||
|
val = readmem8(ctx, real, addr);
|
||||||
|
val = SIGN_EXTEND(val, 0xFF);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
val = readmem16(ctx, real, addr);
|
||||||
|
val = SIGN_EXTEND(val, 0xFFFF);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
val = readmem32(ctx, real, addr);
|
||||||
|
val = SIGN_EXTEND(val, 0xFFFFFFFFUL);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
return readmem64(ctx, real, addr);
|
||||||
|
|
||||||
|
default: log("readmem() bad length %d!\n", len); abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
||||||
|
{
|
||||||
|
GETREAL();
|
||||||
|
CHK_RANGE();
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
|
case 1: writemem8(ctx, val, real, addr); break;
|
||||||
|
case 2: writemem16(ctx, val, real, addr); break;
|
||||||
|
case 4: writemem32(ctx, val, real, addr); break;
|
||||||
|
case 8: writemem64(ctx, val, real, addr); break;
|
||||||
|
default: log("writemem() bad length %d!\n", len); abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// The following functions zero-extend rather than sign-extend
|
||||||
|
//
|
||||||
|
|
||||||
|
ulong readmemzx(ctx_t *ctx, ulong addr, uint len)
|
||||||
|
{
|
||||||
|
GETREAL();
|
||||||
|
CHK_RANGE();
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
|
case 1: return readmem8(ctx, real, addr); break;
|
||||||
|
case 2: return readmem16(ctx, real, addr); break;
|
||||||
|
case 4: return readmem32(ctx, real, addr); break;
|
||||||
|
case 8: return readmem64(ctx, real, addr); break;
|
||||||
|
|
||||||
|
default: log("readmem() bad length %d!\n", len); abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writememzx(ctx_t *ctx, ulong val, ulong addr, uint len)
|
||||||
|
{
|
||||||
|
GETREAL();
|
||||||
|
CHK_RANGE();
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
|
case 1: writemem8(ctx, val, real, addr); break;
|
||||||
|
case 2: writemem16(ctx, val, real, addr); break;
|
||||||
|
case 4: writemem32(ctx, val, real, addr); break;
|
||||||
|
case 8: writemem64(ctx, val, real, addr); break;
|
||||||
|
default: log("writemem() bad length %d!\n", len); abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user