-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathInstructions.jl
More file actions
112 lines (98 loc) · 2.81 KB
/
Instructions.jl
File metadata and controls
112 lines (98 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
include("instr/opc_list.jl")
function gen_jl_block(cpu:: CPU, mem:: PhysicalMemory)
jl_expr = quote end
cpu.jit_rip = @rip(cpu)
cpu.jit_eot = false
cpu.ip_addend = 0
cpu.this_instr_len = 0
nb_instr::UInt64 = 0
while true
b = jit_fetch8_advance(cpu, mem)
println(hex(b))
cpu.jit_insn_tbl[b](cpu, mem, UInt16(b), jl_expr)
#push!(jl_expr.args, l)
nb_instr += 1
# If it is not a branch instruction, generate code for IP update
if !cpu.jit_eot
push!(jl_expr.args, :(@rip_add!(cpu, $(cpu.ip_addend))))
cpu.ip_addend = 0
end
if cpu.jit_eot || cpu.single_stepping
# For type stablization
push!(jl_expr.args, :(return nothing))
break
end
end
println(jl_expr)
@eval f(cpu:: CPU, mem:: PhysicalMemory) = $jl_expr
return JITBlock(f, nb_instr)
end
function find_jl_block(cpu:: CPU, mem:: PhysicalMemory)
#= The julia code blocks are stored by their beginning physical
addresses. The ones with beginning addresses that belong to
the same physical page are stored in a associative map. Each
physical page has its own associative map =#
# Find the associative map. Create one if not found.
phys_ip = logical_to_physical(cpu, CS, UInt64(@ip(cpu)))
phys_page = phys_ip >> 12
if !haskey(cpu.jl_blocks, phys_page)
cpu.jl_blocks[phys_page] = Dict{UInt64, JITBlock}()
end
# Search in the associative map. Translate if not found.
map = cpu.jl_blocks[phys_page]
if haskey(map, phys_ip)
return map[phys_ip]
else
b = gen_jl_block(cpu, mem)
map[phys_ip] = b
return b
end
end
function emu_fetch8_advance(cpu:: CPU, mem:: PhysicalMemory)
b:: UInt8
if (cpu.address_size == 16)
b = ru8(cpu, mem, CS, UInt64(@ip(cpu)))
@ip_add!(cpu, 1)
cpu.this_instr_len += 1
# In emulation mode we keep ip_addend zero to acquire correct
# relative offset on branch instruction (ip + rel + ip_addend)
return b
end
return 0
end
function jit_fetch8_advance(cpu:: CPU, mem:: PhysicalMemory)
b:: UInt8
if (cpu.address_size == 16)
b = ru8(cpu, mem, CS, cpu.jit_rip & 0xffff)
cpu.jit_rip = (cpu.jit_rip + 1) & 0xffff
# Only in JIT mode we need to increase ip_addend
cpu.ip_addend += 1
cpu.this_instr_len += 1
return b
end
return 0
end
function emu_fetch16_advance(cpu:: CPU, mem:: PhysicalMemory)
b:: UInt16
if (cpu.address_size == 16)
b = ru16(cpu, mem, CS, UInt64(@ip(cpu)))
@ip_add!(cpu, 2)
cpu.this_instr_len += 2
# In emulation mode we keep ip_addend zero to acquire correct
# relative offset on branch instruction (ip + rel + ip_addend)
return b
end
return 0
end
function jit_fetch16_advance(cpu:: CPU, mem:: PhysicalMemory)
b:: UInt16
if (cpu.address_size == 16)
b = ru16(cpu, mem, CS, cpu.jit_rip & 0xffff)
cpu.jit_rip = (cpu.jit_rip + 2) & 0xffff
# Only in JIT mode we need to increase ip_addend
cpu.ip_addend += 2
cpu.this_instr_len += 2
return b
end
return 0
end