assembly wip
This commit is contained in:
parent
d6089b3999
commit
b7fa46e540
323
as/k-as.py
323
as/k-as.py
|
@ -303,6 +303,76 @@ def parse_preproc(line):
|
|||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
pconds = {
|
||||
'c': 0b00001,
|
||||
'o': 0b00010,
|
||||
'z': 0b00011,
|
||||
'e': 0b00011,
|
||||
's': 0b00100,
|
||||
'p': 0b00101,
|
||||
'a': 0b00110,
|
||||
'ae': 0b00111,
|
||||
'b': 0b01000,
|
||||
'be': 0b01001,
|
||||
'g': 0b01010,
|
||||
'ge': 0b01011,
|
||||
'l': 0b01100,
|
||||
'le': 0b01101,
|
||||
'cxz': 0b01110,
|
||||
'cxnz': 0b11110,
|
||||
}
|
||||
|
||||
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()
|
||||
sys.exit(1)
|
||||
|
||||
return (mask | pconds[cond]) << 10
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
pfts = {
|
||||
"reg": 0b00001,
|
||||
"imm64": 0b00010,
|
||||
|
||||
"bimm64": 0b00100,
|
||||
"brr": 0b00101,
|
||||
"brri": 0b00110,
|
||||
"brrii": 0b00111,
|
||||
|
||||
"wimm64": 0b01000,
|
||||
"wrr": 0b01001,
|
||||
"wrri": 0b01010,
|
||||
"wrrii": 0b01011,
|
||||
|
||||
"limm64": 0b01100,
|
||||
"lrr": 0b01101,
|
||||
"lrri": 0b01110,
|
||||
"lrrii": 0b01111,
|
||||
|
||||
"qimm64": 0b10000,
|
||||
"qrr": 0b10001,
|
||||
"qrri": 0b10010,
|
||||
"qrrii": 0b10011,
|
||||
}
|
||||
|
||||
def get_fts_mask(ft, line):
|
||||
if ft not in pfts:
|
||||
print("Invalid operand format ({}): {}".format(ft, line))
|
||||
|
||||
else:
|
||||
return pfts[ft]
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def parse_instr(line):
|
||||
if line == None or len(line) == 0:
|
||||
return 0
|
||||
|
@ -318,7 +388,10 @@ def parse_instr(line):
|
|||
|
||||
fellthrough = False
|
||||
|
||||
size = 2
|
||||
size = 4
|
||||
|
||||
# Word 2 (rep|cond|ft1|ft2)
|
||||
w2 = 0
|
||||
|
||||
if instr == "rep":
|
||||
if params == None:
|
||||
|
@ -326,36 +399,46 @@ def parse_instr(line):
|
|||
leave()
|
||||
sys.exit(1)
|
||||
|
||||
instrs.write("%rep ")
|
||||
w2 |= 0x8000 # 16th bit
|
||||
instr, params = params.split(' ', 1)
|
||||
size += 2
|
||||
|
||||
if '.' in instr:
|
||||
w2 |= get_cond_mask(instr.split('.', 1)[1], line)
|
||||
instr_name = instr.split('.', 1)[0]
|
||||
|
||||
else:
|
||||
instr_name = instr
|
||||
|
||||
instr_name = instr.replace('.', '$', 1)
|
||||
instr_args = ''
|
||||
|
||||
if params == None or len(params) == 0:
|
||||
instrs.write("{}".format(instr_name))
|
||||
return 2 # instruction
|
||||
instrs.write("{} ".format(instr_name))
|
||||
instrs.write("%%imm16 {}".format(w2))
|
||||
|
||||
return size
|
||||
|
||||
tok = params.split(',')
|
||||
|
||||
# FT1 and FT2
|
||||
fts = ''
|
||||
|
||||
#
|
||||
# Parse operands, generating fts along the way
|
||||
#
|
||||
for word in tok:
|
||||
word = word.strip()
|
||||
|
||||
instr_args += ' '
|
||||
|
||||
pref = None
|
||||
gotPref = False
|
||||
if len(fts) != 0:
|
||||
fts += ' '
|
||||
|
||||
# memory length prefixes
|
||||
if len(word) > 2 and '[' in word:
|
||||
if word[0] == 'b':
|
||||
pref = "%b"
|
||||
elif word[0] == 'w':
|
||||
pref = "%w"
|
||||
elif word[0] == 'l' or word[0] == 'd':
|
||||
pref = "%l"
|
||||
elif word[0] == 'q':
|
||||
pref = "%q"
|
||||
if word[0] in 'bwlq':
|
||||
fts += word[0]
|
||||
gotPref = True
|
||||
else:
|
||||
print("Bad memory length prefix: {}".format(line))
|
||||
leave()
|
||||
|
@ -364,20 +447,116 @@ def parse_instr(line):
|
|||
word = word[1:].strip()
|
||||
assert(word[0] == '[')
|
||||
|
||||
# [reg+off], [reg+regoff+off] or [imm64]
|
||||
#
|
||||
# Determine memory format and save it into fts
|
||||
#
|
||||
if word[0] == '[':
|
||||
assert(word[-1] == ']')
|
||||
word = word[1:-1]
|
||||
|
||||
if pref == None:
|
||||
#
|
||||
# Make sure we got an access length prefix
|
||||
#
|
||||
if not gotPref:
|
||||
print("Missing access length modifier: {}".format(line))
|
||||
leave()
|
||||
sys.exit(1)
|
||||
|
||||
instr_name += "_m"
|
||||
instr_args += "{}".format(pref)
|
||||
|
||||
#
|
||||
# Offsets
|
||||
#
|
||||
if '+' in word:
|
||||
|
||||
reg1 = "inv"
|
||||
reg2 = "inv"
|
||||
imm1 = '1'
|
||||
imm2 = '0'
|
||||
|
||||
wtok = word.split('+')
|
||||
|
||||
#
|
||||
# [reg] and [reg*imm16]
|
||||
#
|
||||
|
||||
if len(wtok) == 1:
|
||||
if '*' in wtok[0]:
|
||||
assert(len(wtok[0].split('*')) == 2)
|
||||
|
||||
reg2, imm1 = wtok[0].split('*', 1)
|
||||
|
||||
else:
|
||||
reg1 = wtok[0]
|
||||
|
||||
#
|
||||
# [reg+reg], [reg+imm16], [reg*imm16+imm16], [reg+reg*imm16]
|
||||
#
|
||||
elif len(wtok) == 2:
|
||||
# Must be [reg*imm16+imm16]
|
||||
if '*' in wtok[0]:
|
||||
assert(len(wtok[0].split('*')) == 2)
|
||||
assert(is_number(wtok[1].strip()))
|
||||
|
||||
print(wtok)
|
||||
reg2, imm1 = wtok[0].split('*', 1)
|
||||
imm2 = wtok[1]
|
||||
|
||||
# Must be [reg+reg*imm16]
|
||||
elif '*' in wtok[1]:
|
||||
assert(len(wtok[1].split('*')) == 2)
|
||||
|
||||
reg1 = wtok[0]
|
||||
reg2, imm1 = wtok[1].split('*', 1)
|
||||
|
||||
elif is_number(wtok[1].strip()):
|
||||
reg1 = wtok[0]
|
||||
imm2 = wtok[1]
|
||||
|
||||
# Must be [reg+reg]
|
||||
else:
|
||||
reg1 = wtok[0]
|
||||
reg2 = wtok[1]
|
||||
|
||||
#
|
||||
# [reg+reg+imm16], [reg+reg*imm16+imm16]
|
||||
#
|
||||
else:
|
||||
assert(len(wtok) == 3)
|
||||
|
||||
reg1 = wtok[0]
|
||||
imm2 = wtok[2]
|
||||
|
||||
if '*' in wtok[1]:
|
||||
assert(len(wtok[1].split('*')) == 2)
|
||||
reg2, imm1 = wtok[1].split('*', 1)
|
||||
|
||||
else:
|
||||
reg2 = wtok[1]
|
||||
|
||||
#
|
||||
# Update fts and instr_args
|
||||
#
|
||||
|
||||
instr_args += "{}:{} ".format(reg2.strip(), reg1.strip())
|
||||
size += 2
|
||||
|
||||
if imm1 == '1':
|
||||
if imm2 == '0':
|
||||
fts += 'rr'
|
||||
else:
|
||||
fts += 'rri'
|
||||
size += 2
|
||||
instr_args += "%%imm16 {}".format(imm2)
|
||||
|
||||
else:
|
||||
size += 4
|
||||
fts += 'rrii'
|
||||
instr_args += "%%imm16 {} %%imm16 {}".format(imm1, imm2)
|
||||
|
||||
continue
|
||||
|
||||
"""
|
||||
# +2 for A_OFF, +2 for offset, +2 for regoff, +2 for register
|
||||
size += 2 + 2 + 2 + 2
|
||||
instr_args += "off "
|
||||
|
@ -406,47 +585,60 @@ def parse_instr(line):
|
|||
instr_args += "{} {} {}".format(off, regoff, reg)
|
||||
|
||||
continue
|
||||
"""
|
||||
|
||||
# [imm64]
|
||||
#
|
||||
# [imm64] or [reg]
|
||||
#
|
||||
else:
|
||||
# +2 for A_MEM
|
||||
size += 2
|
||||
instr_args += "mem "
|
||||
|
||||
fellthrough = True
|
||||
# FALLTHROUGH
|
||||
|
||||
# for now every immediate is 64-bit
|
||||
if is_number(word):
|
||||
# +2 for A_IMM64, +8 for immediate
|
||||
size += 2 + 8
|
||||
if not fellthrough:
|
||||
instr_name += "_i"
|
||||
instr_args += "%imm64 "
|
||||
instr_args += word
|
||||
fellthrough = False
|
||||
continue
|
||||
|
||||
# preprocessor
|
||||
if word in pdefs:
|
||||
word = pdefs[word]
|
||||
# Fall through
|
||||
|
||||
# for now every immediate is 64-bit
|
||||
if is_number(word):
|
||||
# +8 for immediate
|
||||
size += 8
|
||||
|
||||
if not fellthrough:
|
||||
instr_name += "_i"
|
||||
|
||||
fts += "imm64"
|
||||
|
||||
instr_args += "%%imm64 "
|
||||
instr_args += word
|
||||
|
||||
fellthrough = False
|
||||
continue
|
||||
|
||||
# register
|
||||
if word in pregs:
|
||||
size += 2
|
||||
|
||||
if not fellthrough:
|
||||
instr_name += "_r"
|
||||
fts += "reg"
|
||||
|
||||
else:
|
||||
fts += "rr"
|
||||
|
||||
instr_args += word
|
||||
fellthrough = False
|
||||
continue
|
||||
|
||||
# it's a label (a 64-bit immediate)
|
||||
# +2 for A_IMM64, +8 for immediate
|
||||
size += 2 + 8
|
||||
# +8 for immediate
|
||||
size += 8
|
||||
|
||||
if not fellthrough:
|
||||
instr_name += "_i"
|
||||
instr_args += "%imm64 "
|
||||
|
||||
fts += "imm64"
|
||||
instr_args += "%%imm64 "
|
||||
|
||||
if word[0] == '.':
|
||||
instr_args += plastlabel
|
||||
|
@ -454,31 +646,37 @@ def parse_instr(line):
|
|||
instr_args += word
|
||||
fellthrough = False
|
||||
|
||||
instrs.write("{}{}".format(instr_name, instr_args))
|
||||
#
|
||||
# Compute FT1 and FT2
|
||||
#
|
||||
if ' ' in fts:
|
||||
assert(len(fts.split(' ')) == 2)
|
||||
ft1, ft2 = fts.split(' ')
|
||||
|
||||
w2 |= get_fts_mask(ft1, line) << 5
|
||||
w2 |= get_fts_mask(ft2, line)
|
||||
|
||||
else:
|
||||
assert(len(fts) > 0)
|
||||
w2 |= get_fts_mask(fts, line) << 5
|
||||
|
||||
instrs.write("{} %%imm16 {}{}".format(instr_name, w2, instr_args))
|
||||
return size
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
special_syms = {
|
||||
"%bmem": 0x7001,
|
||||
"%wmem": 0x7002,
|
||||
"%lmem": 0x7004,
|
||||
"%qmem": 0x7008,
|
||||
|
||||
"%boff": 0x7701,
|
||||
"%woff": 0x7702,
|
||||
"%loff": 0x7704,
|
||||
"%qoff": 0x7708,
|
||||
|
||||
"%imm16": 0x7772,
|
||||
"%imm32": 0x7774,
|
||||
"%imm64": 0x7778,
|
||||
|
||||
"%rep": 0x8000
|
||||
"%%imm16",
|
||||
"%%imm32",
|
||||
"%%imm64",
|
||||
"%%signed"
|
||||
}
|
||||
|
||||
def gentext():
|
||||
instrs.seek(0)
|
||||
print(instrs.read())
|
||||
instrs.seek(0)
|
||||
|
||||
text_start = 0x100000
|
||||
data_start = text_start + ptext
|
||||
data_start += (8 - data_start % 8)
|
||||
|
@ -487,11 +685,21 @@ def gentext():
|
|||
tok = line.strip().split(' ')
|
||||
|
||||
for word in tok:
|
||||
if len(word) == 0:
|
||||
continue
|
||||
|
||||
if word in pregs:
|
||||
idx = pregs.index(word)
|
||||
b_text.write(idx.to_bytes(2, byteorder='little', signed=False))
|
||||
continue
|
||||
|
||||
if ':' in word:
|
||||
reg2, reg1 = word.split(':', 1)
|
||||
idx1 = pregs.index(reg1)
|
||||
idx2 = pregs.index(reg2)
|
||||
b_text.write(((idx1 << 8) | idx2).to_bytes(2, byteorder='little', signed=False))
|
||||
continue
|
||||
|
||||
if word in pinstrs:
|
||||
idx = pinstrs.index(word)
|
||||
b_text.write(idx.to_bytes(2, byteorder='little', signed=False))
|
||||
|
@ -508,20 +716,19 @@ def gentext():
|
|||
continue
|
||||
|
||||
if word in special_syms:
|
||||
if word == "%imm16":
|
||||
if word == "%%imm16":
|
||||
lastimm = 2
|
||||
elif word == "%imm32":
|
||||
elif word == "%%imm32":
|
||||
lastimm = 4
|
||||
elif word == "%imm64":
|
||||
elif word == "%%imm64":
|
||||
lastimm = 8
|
||||
|
||||
if word[2:] == "off" and word[0] == '%':
|
||||
elif word == "%%signed":
|
||||
lastimm = 2
|
||||
isSigned = True
|
||||
else:
|
||||
isSigned = False
|
||||
|
||||
b_text.write(special_syms[word].to_bytes(2, byteorder='little', signed=isSigned))
|
||||
continue
|
||||
|
||||
if is_number(word):
|
||||
|
|
|
@ -33,7 +33,7 @@ strcmp:
|
|||
strncmp:
|
||||
mov rcx, ax2
|
||||
|
||||
.1:
|
||||
.0:
|
||||
cmp b[ax0], b[ax1]
|
||||
jmp.nz .1
|
||||
|
||||
|
@ -42,7 +42,7 @@ strncmp:
|
|||
|
||||
inc ax0
|
||||
inc ax1
|
||||
loop strcmp
|
||||
loop .0
|
||||
|
||||
.1:
|
||||
mov rax, b[ax0]
|
||||
|
|
67
vm/in/INSTRS
67
vm/in/INSTRS
|
@ -28,7 +28,7 @@ stop
|
|||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
!not rm
|
||||
not rm
|
||||
|
||||
#
|
||||
# Bitwise OR operation
|
||||
|
@ -38,7 +38,8 @@ stop
|
|||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
!or rm rim
|
||||
or rm rim
|
||||
orf rm rim
|
||||
|
||||
#
|
||||
# Bitwise AND operation
|
||||
|
@ -48,7 +49,8 @@ stop
|
|||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
!and rm rim
|
||||
and rm rim
|
||||
andf rm rim
|
||||
|
||||
#
|
||||
# Bitwise XOR operation
|
||||
|
@ -58,11 +60,14 @@ stop
|
|||
# Clears OF and CF
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
!xor rm rim
|
||||
xor rm rim
|
||||
xorf rm rim
|
||||
|
||||
# To document
|
||||
!shl rm rim
|
||||
!shr rm rim
|
||||
shl rm rim
|
||||
shr rm rim
|
||||
shlf rm rim
|
||||
shrf rm rim
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Arithmetic instructions #
|
||||
|
@ -82,7 +87,8 @@ stop
|
|||
# Treats $1 and $2 as signed values
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
!sgn rm rim
|
||||
sgn rm rim
|
||||
sgnf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical NEG operation
|
||||
|
@ -93,7 +99,8 @@ stop
|
|||
# Sets OF if $1 == $LONG_MIN; clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
!neg rm
|
||||
neg rm
|
||||
negf rm
|
||||
|
||||
#
|
||||
# Arithmetical INC operation
|
||||
|
@ -104,7 +111,8 @@ stop
|
|||
# Sets OF if $1 == $LONG_MAX, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
!inc rm
|
||||
inc rm
|
||||
incf rm
|
||||
|
||||
#
|
||||
# Arithmetical DEC operation
|
||||
|
@ -115,7 +123,8 @@ stop
|
|||
# Sets OF if $1 == $LONG_MIN, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
!dec rm
|
||||
dec rm
|
||||
decf rm
|
||||
|
||||
#
|
||||
# Arithmetical ADD operation
|
||||
|
@ -126,7 +135,8 @@ stop
|
|||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
!add rm rim
|
||||
add rm rim
|
||||
addf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical SUB operation
|
||||
|
@ -137,7 +147,8 @@ stop
|
|||
# Sets OF is signed integer overflow occur, clears it otherwise
|
||||
# Sets ZF and SF according to the result
|
||||
#
|
||||
!sub rm rim
|
||||
sub rm rim
|
||||
subf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned MUL operation
|
||||
|
@ -147,7 +158,8 @@ stop
|
|||
# Sets CF and OF if HI($1 * $2) > 0, clears them otherwise
|
||||
# Preserves ZF and SF
|
||||
#
|
||||
!mul rm rim
|
||||
mul rm rim
|
||||
mulf rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned DIV operation
|
||||
|
@ -156,7 +168,7 @@ stop
|
|||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
!div rm rim
|
||||
div rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned MOD operation
|
||||
|
@ -165,7 +177,7 @@ stop
|
|||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
!mod rm rim
|
||||
mod rm rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned 128-bit MUL operation
|
||||
|
@ -177,6 +189,7 @@ stop
|
|||
# Preserves ZF and SF
|
||||
#
|
||||
mul2 rim
|
||||
mul2f rim
|
||||
|
||||
#
|
||||
# Arithmetical unsigned combined DIV and MOD operations
|
||||
|
@ -222,8 +235,8 @@ cmp rim rim
|
|||
#
|
||||
# RIP = CR1 + $1
|
||||
#
|
||||
!j ri
|
||||
!jmp ri
|
||||
j ri
|
||||
jmp ri
|
||||
|
||||
#
|
||||
# RCX-dependent jump (LOOP) instruction
|
||||
|
@ -233,7 +246,7 @@ cmp rim rim
|
|||
# RIP = CR1 + $1
|
||||
# FI
|
||||
#
|
||||
!loop ri
|
||||
loop ri
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Movement instructions #
|
||||
|
@ -251,14 +264,14 @@ cmp rim rim
|
|||
#
|
||||
# Preserves all flags
|
||||
#
|
||||
!lea rm m
|
||||
lea rm m
|
||||
|
||||
#
|
||||
# Movement (MOV) instruction
|
||||
#
|
||||
# $1 = $2
|
||||
#
|
||||
!mov rm rim
|
||||
mov rm rim
|
||||
|
||||
#
|
||||
# Exchange (XCHG) instruction
|
||||
|
@ -267,7 +280,7 @@ cmp rim rim
|
|||
# $1 = $2
|
||||
# $2 = $_
|
||||
#
|
||||
!xchg rm rim
|
||||
xchg rm rim
|
||||
|
||||
#
|
||||
# Compare-and-exchange (CMPXCHG) instruction
|
||||
|
@ -305,7 +318,7 @@ cmpxchg rm rim
|
|||
# #STA if RSP MOD 8 > 0
|
||||
# #STU if RSP > RBP
|
||||
#
|
||||
!push rim
|
||||
push rim
|
||||
|
||||
#
|
||||
# POP value from stack
|
||||
|
@ -318,7 +331,7 @@ cmpxchg rm rim
|
|||
# #STA if RSP MOD 8 > 0
|
||||
# #STU if RSP >= RBP
|
||||
#
|
||||
!pop rm
|
||||
pop rm
|
||||
|
||||
#
|
||||
# Unconditional jump with possible return (CALL)
|
||||
|
@ -329,7 +342,7 @@ cmpxchg rm rim
|
|||
# Throws:
|
||||
# See PUSH and JMP
|
||||
#
|
||||
!call rim
|
||||
call rim
|
||||
|
||||
#
|
||||
# Return to caller (RET)
|
||||
|
@ -339,7 +352,7 @@ cmpxchg rm rim
|
|||
# Throws:
|
||||
# See POP
|
||||
#
|
||||
!ret
|
||||
ret
|
||||
|
||||
#
|
||||
# Make new stack frame (ENTER)
|
||||
|
@ -358,7 +371,7 @@ enter
|
|||
# RBP = *RSP
|
||||
# RSP = RSP + 8
|
||||
#
|
||||
!leave
|
||||
leave
|
||||
|
||||
#---------------------------------------------------------------------------#
|
||||
# Supervisor only instructions #
|
||||
|
@ -460,7 +473,7 @@ prn rim
|
|||
# (cause register dump on standard error)
|
||||
# (wait for user input before proceeeding)
|
||||
#
|
||||
!break
|
||||
break
|
||||
|
||||
#
|
||||
# Step-by-step execution (STEP)
|
||||
|
|
|
@ -3,27 +3,27 @@
|
|||
|
||||
#include <in/instrs.h>
|
||||
|
||||
IMPL_COND(sgn);
|
||||
IMPL_COND(neg);
|
||||
IMPL_COND(inc);
|
||||
IMPL_COND(dec);
|
||||
IMPL_COND(add);
|
||||
IMPL_COND(sub);
|
||||
IMPL_COND(mul);
|
||||
IMPL_COND(div);
|
||||
IMPL_COND(mod);
|
||||
IMPL_COND(mul2);
|
||||
IMPL_COND(div2);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(sgn)
|
||||
{
|
||||
v1 = (long)v2 < 0 ? (ulong)-1L : 1;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(sgnf)
|
||||
{
|
||||
v1 = (long)v2 < 0 ? (ulong)-1L : 1;
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_1(neg)
|
||||
{
|
||||
v1 = ~v1 + 1;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_1(negf)
|
||||
{
|
||||
if (v1 == 0) flg |= CF;
|
||||
|
||||
|
@ -41,6 +41,12 @@ IMPL_OUT_ZSF;
|
|||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_1(inc)
|
||||
{
|
||||
v1++;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_1(incf)
|
||||
{
|
||||
if (v1 == LONG_MAX) flg |= OF;
|
||||
else flg &= ~OF;
|
||||
|
@ -50,6 +56,12 @@ IMPL_START_1(inc)
|
|||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_1(dec)
|
||||
{
|
||||
v1--;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_1(decf)
|
||||
{
|
||||
if (v1 == LONG_MIN) flg |= OF;
|
||||
else flg &= ~OF;
|
||||
|
@ -61,6 +73,12 @@ IMPL_OUT_ZSF;
|
|||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(add)
|
||||
{
|
||||
v1 += v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(addf)
|
||||
{
|
||||
if (v1 + v2 < v1) flg |= OF;
|
||||
else flg &= ~OF;
|
||||
|
@ -75,6 +93,12 @@ IMPL_START_2(add)
|
|||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_2(sub)
|
||||
{
|
||||
v1 -= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(subf)
|
||||
{
|
||||
if (v1 < v2) flg |= CF;
|
||||
else flg &= ~CF;
|
||||
|
@ -89,7 +113,7 @@ IMPL_START_2(sub)
|
|||
IMPL_OUT_ZSF;
|
||||
|
||||
//
|
||||
// i_sub but discards result
|
||||
// i_subf but discards result
|
||||
//
|
||||
IMPL_START_2(cmp)
|
||||
{
|
||||
|
@ -132,6 +156,13 @@ static void multiply(ulong u, ulong v, ulong *hi, ulong *lo)
|
|||
}
|
||||
|
||||
IMPL_START_2(mul)
|
||||
{
|
||||
ulong hi;
|
||||
multiply(v1, v2, &hi, &v1);
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(mulf)
|
||||
{
|
||||
ulong hi;
|
||||
|
||||
|
@ -149,7 +180,14 @@ IMPL_START_2(mul)
|
|||
}
|
||||
IMPL_OUT;
|
||||
|
||||
|
||||
IMPL_START_1(mul2)
|
||||
{
|
||||
multiply(rax, v1, &rdx, &rax);
|
||||
}
|
||||
IMPL_END;
|
||||
|
||||
IMPL_START_1(mul2f)
|
||||
{
|
||||
multiply(rax, v1, &rdx, &rax);
|
||||
|
||||
|
|
50
vm/in/cond.h
50
vm/in/cond.h
|
@ -1,50 +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.
|
||||
|
||||
/*
|
||||
#define _IMPL_IF_COND(name, suf, cond) \
|
||||
IMPL_START_0(name##$##suf) \
|
||||
{ \
|
||||
if (cond) { \
|
||||
i_##name(ctx, p1, p2); \
|
||||
} \
|
||||
} \
|
||||
IMPL_END \
|
||||
|
||||
#define IMPL_COND(name) \
|
||||
\
|
||||
_IMPL_IF_COND(name, cxz, rcx == 0); \
|
||||
_IMPL_IF_COND(name, cxnz, rcx != 0); \
|
||||
\
|
||||
_IMPL_IF_COND(name, c, flg&CF); \
|
||||
_IMPL_IF_COND(name, o, flg&OF); \
|
||||
\
|
||||
_IMPL_IF_COND(name, nc, !(flg&CF)); \
|
||||
_IMPL_IF_COND(name, no, !(flg&OF)); \
|
||||
\
|
||||
_IMPL_IF_COND(name, z, flg&ZF); \
|
||||
_IMPL_IF_COND(name, s, flg&SF); \
|
||||
_IMPL_IF_COND(name, p, flg&PF); \
|
||||
\
|
||||
_IMPL_IF_COND(name, nz, !(flg&ZF)); \
|
||||
_IMPL_IF_COND(name, ns, !(flg&SF)); \
|
||||
_IMPL_IF_COND(name, np, !(flg&PF)); \
|
||||
\
|
||||
_IMPL_IF_COND(name, e, flg&ZF); \
|
||||
_IMPL_IF_COND(name, eq, flg&ZF); \
|
||||
_IMPL_IF_COND(name, ne, !(flg&ZF)); \
|
||||
\
|
||||
_IMPL_IF_COND(name, b, flg&CF); \
|
||||
_IMPL_IF_COND(name, be, flg&ZF || flg&CF); \
|
||||
\
|
||||
_IMPL_IF_COND(name, a, !(flg&CF || flg&ZF)); \
|
||||
_IMPL_IF_COND(name, ae, !(flg&CF)); \
|
||||
\
|
||||
_IMPL_IF_COND(name, l, !!(flg&SF) != !!(flg&OF)); \
|
||||
_IMPL_IF_COND(name, le, flg&ZF || (!!(flg&SF) != !!(flg&OF))); \
|
||||
\
|
||||
_IMPL_IF_COND(name, g, !(flg&ZF) && (!!(flg&SF) == !!(flg&OF))); \
|
||||
_IMPL_IF_COND(name, ge, !!(flg&SF) == !!(flg&OF)); \
|
||||
*/
|
||||
|
||||
#define IMPL_COND(name)
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include <in/instrs.h>
|
||||
|
||||
IMPL_COND(break);
|
||||
|
||||
IMPL_START_0(break)
|
||||
{
|
||||
log("\nExecuting BREAK INSTR\n");
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
SET_ZF(v); \
|
||||
SET_SF(v)
|
||||
|
||||
#define _SET_ZSPF(v) \
|
||||
#define SET_ZSPF(v) \
|
||||
SET_ZF(v); \
|
||||
SET_SF(v); \
|
||||
SET_PF(v)
|
||||
|
|
|
@ -3,10 +3,17 @@
|
|||
|
||||
#include <pc/arch.h>
|
||||
|
||||
#include <in/cond.h>
|
||||
#include <in/flags.h>
|
||||
#include <in/arch_i.h>
|
||||
|
||||
#define GETV(v, p) \
|
||||
ulong v; \
|
||||
assert(p); \
|
||||
if (ACC_FMT_IS_MEM(p->type)) \
|
||||
v = readmem(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 *ret) \
|
||||
{
|
||||
|
@ -14,13 +21,13 @@ bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *ret) \
|
|||
#define IMPL_START_1(name) \
|
||||
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *ret) \
|
||||
{ \
|
||||
ulong v1 = p1->val;
|
||||
GETV(v1, p1);
|
||||
|
||||
#define IMPL_START_2(name) \
|
||||
bool i_##name(ctx_t *ctx, acc_t *p1, acc_t *p2, ulong *ret) \
|
||||
{ \
|
||||
ulong v1 = p1->val; \
|
||||
ulong v2 = p2->val;
|
||||
GETV(v1, p1); \
|
||||
GETV(v2, p2);
|
||||
|
||||
#define IMPL_OUT_ZSF \
|
||||
SET_ZSF(v1); \
|
||||
|
|
|
@ -3,10 +3,6 @@
|
|||
|
||||
#include <in/instrs.h>
|
||||
|
||||
IMPL_COND(j);
|
||||
IMPL_COND(jmp);
|
||||
IMPL_COND(loop);
|
||||
|
||||
//
|
||||
// Jump instructions
|
||||
//
|
||||
|
|
|
@ -3,12 +3,11 @@
|
|||
|
||||
#include <in/instrs.h>
|
||||
|
||||
IMPL_COND(not);
|
||||
IMPL_COND(and);
|
||||
IMPL_COND(or);
|
||||
IMPL_COND(xor);
|
||||
IMPL_COND(shl);
|
||||
IMPL_COND(shr);
|
||||
IMPL_START_1(not)
|
||||
{
|
||||
v1 = ~v1;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
@ -21,15 +20,28 @@ IMPL_START_2(test)
|
|||
IMPL_END;
|
||||
|
||||
IMPL_START_2(and)
|
||||
{
|
||||
v1 &= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(andf)
|
||||
{
|
||||
flg &= ~OF;
|
||||
flg &= ~CF;
|
||||
v1 &= v2;
|
||||
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(or)
|
||||
{
|
||||
v1 |= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(orf)
|
||||
{
|
||||
flg &= ~OF;
|
||||
flg &= ~CF;
|
||||
|
@ -38,6 +50,12 @@ IMPL_START_2(or)
|
|||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_2(xor)
|
||||
{
|
||||
v1 ^= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(xorf)
|
||||
{
|
||||
flg &= ~OF;
|
||||
flg &= ~CF;
|
||||
|
@ -45,21 +63,31 @@ IMPL_START_2(xor)
|
|||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
IMPL_START_2(shl)
|
||||
{
|
||||
v1 <<= v2;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(shlf)
|
||||
{
|
||||
v1 <<= v2;
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_2(shr)
|
||||
{
|
||||
v1 >>= v2;
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
IMPL_START_1(not)
|
||||
{
|
||||
v1 = ~v1;
|
||||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_START_2(shrf)
|
||||
{
|
||||
v1 >>= v2;
|
||||
}
|
||||
IMPL_OUT_ZSF;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
|
17
vm/in/mov.c
17
vm/in/mov.c
|
@ -3,18 +3,6 @@
|
|||
|
||||
#include <in/instrs.h>
|
||||
|
||||
IMPL_COND(lea);
|
||||
IMPL_COND(mov);
|
||||
IMPL_COND(xchg);
|
||||
IMPL_COND(cmpxchg);
|
||||
|
||||
/*
|
||||
IMPL_COND(xchgb);
|
||||
IMPL_COND(xchgw);
|
||||
IMPL_COND(xchgl);
|
||||
IMPL_COND(xchgt);
|
||||
*/
|
||||
|
||||
//
|
||||
// Movement instructions
|
||||
//
|
||||
|
@ -53,11 +41,6 @@ IMPL_START_2(movt)
|
|||
}
|
||||
IMPL_OUT;
|
||||
|
||||
IMPL_COND(movb);
|
||||
IMPL_COND(movw);
|
||||
IMPL_COND(movl);
|
||||
IMPL_COND(movt);
|
||||
|
||||
IMPL_START_2(xchg)
|
||||
{
|
||||
ulong t = v1;
|
||||
|
|
|
@ -3,12 +3,6 @@
|
|||
|
||||
#include <in/instrs.h>
|
||||
|
||||
IMPL_COND(push);
|
||||
IMPL_COND(pop);
|
||||
IMPL_COND(call);
|
||||
IMPL_COND(ret);
|
||||
IMPL_COND(leave);
|
||||
|
||||
//
|
||||
// Stack manipulation instructions
|
||||
//
|
||||
|
|
|
@ -36,9 +36,9 @@ Values for COND:
|
|||
Highest (6th) bit of COND indicates negation
|
||||
|
||||
Fx values:
|
||||
0000 (none)
|
||||
0001 reg
|
||||
0010 imm64
|
||||
00000 (none)
|
||||
00001 reg
|
||||
00010 imm64
|
||||
|
||||
xxx00 [imm64]
|
||||
xxx01 [reg+reg] code(reg)|code(reg)
|
||||
|
|
118
vm/pc/decd.c
118
vm/pc/decd.c
|
@ -22,7 +22,8 @@ static void check_param_type(ctx_t *ctx, uint prm, uchar fmt)
|
|||
|
||||
if (!ok)
|
||||
_except(ctx, E_ILL,
|
||||
"FT1 or FT2 not matching INSTR's expected parameter types");
|
||||
"FT1 or FT2 not matching INSTR's expected parameter types: "
|
||||
"fmt=0x%x prm=0x%x", fmt, prm);
|
||||
}
|
||||
|
||||
void decode(ctx_t *ctx)
|
||||
|
@ -66,7 +67,7 @@ void decode(ctx_t *ctx)
|
|||
|
||||
in = &ctx->i[w1];
|
||||
|
||||
if (!nomore)
|
||||
if (nomore)
|
||||
goto skip_w2;
|
||||
|
||||
//
|
||||
|
@ -147,7 +148,7 @@ static void checkreg(ctx_t *ctx, uint reg, bool inv_is_ok)
|
|||
}
|
||||
|
||||
if (ctx->r[reg].flags & (RES | CTL))
|
||||
_except(ctx, E_ACC, "Reserved REG: %u", reg);
|
||||
//_except(ctx, E_ACC, "Reserved REG: %u", reg);
|
||||
|
||||
if (ctx->r[reg].flags & SYS)
|
||||
if (cr0 & UF)
|
||||
|
@ -159,7 +160,7 @@ static void checkreg(ctx_t *ctx, uint reg, bool inv_is_ok)
|
|||
//
|
||||
void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
|
||||
{
|
||||
uint mlen, mfmt, reg1, reg2, imm1 = 0, imm2 = 0;
|
||||
uint mlen, mfmt;
|
||||
ushort temp;
|
||||
|
||||
p->type = fmt;
|
||||
|
@ -170,6 +171,8 @@ void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
|
|||
checkreg(ctx, p->reg, 0);
|
||||
|
||||
p->val = R(p->reg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
else if (fmt == A_IMM64)
|
||||
|
@ -178,6 +181,8 @@ void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
|
|||
p->val |= (ulong)ctx->get(ctx) << 16;
|
||||
p->val |= (ulong)ctx->get(ctx) << 32;
|
||||
p->val |= (ulong)ctx->get(ctx) << 48;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
assert(ACC_FMT_IS_MEM(fmt));
|
||||
|
@ -210,41 +215,45 @@ void extract_param(ctx_t *ctx, acc_t *p, uchar fmt)
|
|||
case AM_RRI:
|
||||
case AM_RRII:
|
||||
temp = ctx->get(ctx);
|
||||
reg1 = temp >> 8;
|
||||
reg2 = temp & 0xFF;
|
||||
p->reg1 = temp >> 8;
|
||||
p->reg2 = temp & 0xFF;
|
||||
|
||||
checkreg(ctx, reg1, 0);
|
||||
checkreg(ctx, reg2, 1);
|
||||
checkreg(ctx, p->reg1, 1);
|
||||
checkreg(ctx, p->reg2, 1);
|
||||
|
||||
if (fmt == AM_RRI)
|
||||
if (mfmt == AM_RRI)
|
||||
{
|
||||
imm1 = 1;
|
||||
imm2 = ctx->get(ctx);
|
||||
p->imm1 = 1;
|
||||
p->imm2 = ctx->get(ctx);
|
||||
}
|
||||
|
||||
else if (fmt == AM_RRII)
|
||||
else if (mfmt == AM_RRII)
|
||||
{
|
||||
imm1 = ctx->get(ctx);
|
||||
imm2 = ctx->get(ctx);
|
||||
p->imm1 = ctx->get(ctx);
|
||||
p->imm2 = ctx->get(ctx);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
p->imm1 = 1;
|
||||
p->imm2 = 0;
|
||||
}
|
||||
|
||||
p->addr = R(reg1) + R(reg2) * imm1 + (long)imm2;
|
||||
p->addr = R(p->reg1) + R(p->reg2) * p->imm1 + (long)p->imm2;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
_except(ctx, E_ILL, "Invalid MFMT for access: %x", fmt);
|
||||
}
|
||||
|
||||
p->val = readmem(ctx, p->addr, p->mlen);
|
||||
}
|
||||
|
||||
static bool eval_cond(ctx_t *ctx, uint cond)
|
||||
{
|
||||
bool neg = cond & (1 << 5);
|
||||
bool neg = cond & (1 << 4);
|
||||
bool ok;
|
||||
|
||||
cond &= ~(1 << 5);
|
||||
cond &= ~(1 << 4);
|
||||
|
||||
switch (cond)
|
||||
{
|
||||
|
@ -271,81 +280,12 @@ static bool eval_cond(ctx_t *ctx, uint cond)
|
|||
case CD_CXZ: ok = !rcx; break;
|
||||
|
||||
default:
|
||||
_except(ctx, E_ILL, "Invalid COND value: %x", cond);
|
||||
_except(ctx, E_ILL, "Invalid COND value: 0x%x", (neg?cond|(1<<4):cond));
|
||||
}
|
||||
|
||||
return neg ? !ok : !!ok;
|
||||
}
|
||||
|
||||
char *cond_suffixes[] =
|
||||
{
|
||||
"",
|
||||
".c"
|
||||
};
|
||||
|
||||
static void dump_acc(ctx_t *ctx, acc_t *p)
|
||||
{
|
||||
uint mfmt;
|
||||
|
||||
if (p->type == A_REG)
|
||||
log("%s", ctx->r[p->reg].name);
|
||||
|
||||
else if (p->type == A_IMM64)
|
||||
log("imm64:0x%016lX", p->val);
|
||||
|
||||
else
|
||||
{
|
||||
log("%c[", getmempref(p->mlen));
|
||||
|
||||
mfmt = p->type & AM_MFMT_MASK;
|
||||
|
||||
if (mfmt == AM_IMM64)
|
||||
log("imm64:");
|
||||
|
||||
else if (mfmt == AM_RR)
|
||||
log("rr:");
|
||||
|
||||
else if (mfmt == AM_RRI)
|
||||
log("rri:");
|
||||
|
||||
else if (mfmt == AM_RRII)
|
||||
log("rrii:");
|
||||
|
||||
log("0x%016lX]", p->addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_instr(
|
||||
ctx_t *ctx, instr_t *in,
|
||||
acc_t *p1, acc_t *p2,
|
||||
bool lock, bool rep,
|
||||
uint cond, ulong pc)
|
||||
{
|
||||
log("0x%016lX: ", pc);
|
||||
|
||||
if (lock)
|
||||
log("lock ");
|
||||
|
||||
if (rep)
|
||||
log("rep ");
|
||||
|
||||
if (cond)
|
||||
log("cond%u ", cond);
|
||||
|
||||
log("%s ", in->full);
|
||||
|
||||
if (p1) {
|
||||
dump_acc(ctx, p1);
|
||||
|
||||
if (p2) {
|
||||
log(", ");
|
||||
dump_acc(ctx, p2);
|
||||
}
|
||||
}
|
||||
|
||||
log("\n");
|
||||
}
|
||||
|
||||
//
|
||||
// Executes an instruction
|
||||
//
|
||||
|
|
13
vm/pc/decd.h
13
vm/pc/decd.h
|
@ -21,7 +21,7 @@ enum
|
|||
BITS_COND = (1 << 14) | (1 << 13) | (1 << 12)
|
||||
| (1 << 11) | (1 << 10),
|
||||
|
||||
COND_SHIFT = 8,
|
||||
COND_SHIFT = 10,
|
||||
|
||||
Fx_MASK = 0x1F,
|
||||
F1_SHIFT = 5,
|
||||
|
@ -65,6 +65,8 @@ struct acc_t
|
|||
ulong addr;
|
||||
uint mlen;
|
||||
|
||||
// For instruction dumping ONLY
|
||||
ushort reg1, reg2, imm1, imm2;
|
||||
};
|
||||
|
||||
enum { NOPRM, P_REG, P_IMM, P_MEM=4 };
|
||||
|
@ -93,3 +95,12 @@ void extract_param(ctx_t *ctx,
|
|||
acc_t *p,
|
||||
uchar fmt);
|
||||
|
||||
void dump_instr(ctx_t *ctx,
|
||||
instr_t *in,
|
||||
acc_t *p1,
|
||||
acc_t *p2,
|
||||
bool lock,
|
||||
bool rep,
|
||||
uint cond,
|
||||
ulong pc);
|
||||
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
// 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 <pc/arch.h>
|
||||
|
||||
char *cond_suffixes[] =
|
||||
{
|
||||
"",
|
||||
".c"
|
||||
};
|
||||
|
||||
static void dump_acc(ctx_t *ctx, acc_t *p)
|
||||
{
|
||||
uint mfmt;
|
||||
|
||||
if (p->type == A_REG)
|
||||
log("%s", ctx->r[p->reg].name);
|
||||
|
||||
else if (p->type == A_IMM64)
|
||||
log("0x%lX", p->val);
|
||||
|
||||
else
|
||||
{
|
||||
log("%c[", getmempref(p->mlen));
|
||||
|
||||
mfmt = p->type & AM_MFMT_MASK;
|
||||
|
||||
if (mfmt == AM_IMM64)
|
||||
log("0x%lX]", p->addr);
|
||||
|
||||
else if (mfmt == AM_RR)
|
||||
{
|
||||
if (p->reg1 && p->reg2)
|
||||
log("%s+%s]", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
|
||||
|
||||
else log("%s]", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
|
||||
}
|
||||
|
||||
else if (mfmt == AM_RRI)
|
||||
{
|
||||
if (p->reg1 && p->reg2)
|
||||
log("%s+%s+%lX]", ctx->r[p->reg1].name,
|
||||
ctx->r[p->reg2].name, p->imm2);
|
||||
|
||||
else log("%s+%lX]", ctx->r[p->reg1 ? p->reg1 : p->reg2].name, p->imm2);
|
||||
}
|
||||
|
||||
else if (mfmt == AM_RRII)
|
||||
{
|
||||
if (p->reg1)
|
||||
log("%s+%s*0x%x+0x%x]",
|
||||
ctx->r[p->reg1].name,
|
||||
ctx->r[p->reg2].name,
|
||||
p->imm1, p->imm2);
|
||||
else
|
||||
log("%s*0x%x+0x%x]",
|
||||
ctx->r[p->reg2].name,
|
||||
p->imm1, p->imm2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_instr(
|
||||
ctx_t *ctx, instr_t *in,
|
||||
acc_t *p1, acc_t *p2,
|
||||
bool lock, bool rep,
|
||||
uint cond, ulong pc)
|
||||
{
|
||||
log("0x%lX: ", pc);
|
||||
|
||||
if (lock)
|
||||
log("lock ");
|
||||
|
||||
if (rep)
|
||||
log("rep ");
|
||||
|
||||
if (cond)
|
||||
log("c%x", cond);
|
||||
|
||||
log("\t");
|
||||
|
||||
log("%s\t", in->name);
|
||||
|
||||
if (p1) {
|
||||
dump_acc(ctx, p1);
|
||||
|
||||
if (p2) {
|
||||
log(", ");
|
||||
dump_acc(ctx, p2);
|
||||
}
|
||||
}
|
||||
|
||||
log("\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue