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:
|
||||
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
|
||||
|
||||
itoa_test:
|
||||
|
@ -9,7 +9,6 @@
|
||||
//
|
||||
dev_t *devctl_common(ctx_t *ctx, ulong v1, ulong v2)
|
||||
{
|
||||
|
||||
dev_t *dev = devget(ctx, v1);
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
107
vm/in/INSTRS
107
vm/in/INSTRS
@ -273,6 +273,13 @@ lea rm m
|
||||
#
|
||||
mov rm rim
|
||||
|
||||
#
|
||||
# Movement with zero-extension (MOVZX) instruction
|
||||
#
|
||||
# $1 = ZeroExtend($2)
|
||||
#
|
||||
movzx rm m
|
||||
|
||||
#
|
||||
# Exchange (XCHG) instruction
|
||||
#
|
||||
@ -297,12 +304,6 @@ xchg rm rim
|
||||
#
|
||||
cmpxchg rm rim
|
||||
|
||||
# Undocumented
|
||||
# movb rm rim
|
||||
# movw rm rim
|
||||
# movl rm rim
|
||||
# movt rm rim
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Stack manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -375,6 +376,10 @@ enter i
|
||||
#
|
||||
leave
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# String manipulation instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Supervisor only instructions #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -382,15 +387,6 @@ leave
|
||||
pushf
|
||||
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)
|
||||
#
|
||||
@ -405,6 +401,32 @@ devctl 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 #
|
||||
#---------------------------------------------------------------------------#
|
||||
@ -422,7 +444,7 @@ iocall rim rim
|
||||
nop
|
||||
|
||||
#
|
||||
# Get code/date offset (GCO/GCD)
|
||||
# Get code/data offset (GCO/GCD)
|
||||
#
|
||||
# $1 = CR1 (GCO)
|
||||
# $1 = CR2 (GCD)
|
||||
@ -430,31 +452,6 @@ nop
|
||||
gco 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)
|
||||
#
|
||||
@ -488,4 +485,32 @@ break
|
||||
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;
|
||||
|
||||
//
|
||||
// Misc. instructions
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(prn)
|
||||
{
|
||||
if (p1->mlen > 1) {
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
rax = rbx = rcx = rdx = 0;
|
||||
@ -53,3 +79,5 @@ IMPL_START_0(cln)
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <in/flags.h>
|
||||
#include <in/arch_i.h>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define GETV(v, p) \
|
||||
ulong v; \
|
||||
assert(p); \
|
||||
@ -13,6 +15,14 @@
|
||||
v = readmem(ctx, p->addr, p->mlen); \
|
||||
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) \
|
||||
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; \
|
||||
}
|
||||
|
||||
//
|
||||
// Consistency checks
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define CHK_SUPERV() \
|
||||
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"); \
|
||||
}
|
||||
|
||||
//
|
||||
// Common operations
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#define PUSH(v) \
|
||||
rsp -= 8; \
|
||||
writemem64(ctx, v, rsp);
|
||||
writemem(ctx, v, rsp, 8);
|
||||
|
||||
#define POP(v) \
|
||||
v = readmem64(ctx, rsp); \
|
||||
v = readmem(ctx, rsp, 8); \
|
||||
rsp += 8;
|
||||
|
||||
#define JUMP(v) \
|
||||
rip = v + cr1
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
44
vm/in/mov.c
44
vm/in/mov.c
@ -3,9 +3,13 @@
|
||||
|
||||
#include <in/instrs.h>
|
||||
|
||||
//
|
||||
// Movement instructions
|
||||
//
|
||||
IMPL_START_1(lea)
|
||||
{
|
||||
v1 = p2->addr;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_2(mov)
|
||||
{
|
||||
@ -13,33 +17,14 @@ IMPL_START_2(mov)
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(movb)
|
||||
IMPL_START_1(movzx)
|
||||
{
|
||||
v1 = (v1 & 0xFFFFFFFFFFFFFF00)
|
||||
| (v2 & 0x00000000000000FF);
|
||||
GETVZX(v2, p2);
|
||||
v1 = v2;
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -49,11 +34,6 @@ IMPL_START_2(xchg)
|
||||
}
|
||||
IMPL_OUT_2;
|
||||
|
||||
IMPL_START_1(lea)
|
||||
{
|
||||
v1 = p2->addr;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(cmpxchg)
|
||||
{
|
||||
@ -69,6 +49,8 @@ IMPL_START_2(cmpxchg)
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
IMPL_START_1(gco)
|
||||
{
|
||||
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
|
||||
#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);
|
||||
|
||||
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);
|
||||
|
||||
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/decd.h>
|
||||
#include <in/arch_i.h>
|
||||
|
168
vm/pc/mem.c
168
vm/pc/mem.c
@ -3,33 +3,7 @@
|
||||
|
||||
#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) \
|
||||
if (addr % alignof(type) > 0) { \
|
||||
@ -38,32 +12,23 @@ void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
||||
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;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
ulong val = ctx->mp[real++];
|
||||
@ -72,10 +37,8 @@ ulong readmem32(ctx_t *ctx, ulong addr)
|
||||
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);
|
||||
|
||||
ulong val = (ulong)ctx->mp[real++];
|
||||
@ -86,11 +49,10 @@ ulong readmem64(ctx_t *ctx, ulong addr)
|
||||
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];
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
ctx->mp[real++] = val & 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);
|
||||
|
||||
ctx->mp[real++] = val;
|
||||
@ -133,3 +89,103 @@ void writemem64(ctx_t *ctx, ulong val, ulong addr)
|
||||
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…
x
Reference in New Issue
Block a user