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
|
//riscv epilog for dynarec
//Save stuff, prepare stack and register
//called with pointer to emu as 1st parameter
//and address to jump to as 2nd parameter
.text
.align 4
.global rv64_epilog
.global rv64_epilog_fast
rv64_epilog:
//update register -> emu
sd x16, (a0)
sd x17, 8(a0)
sd x18, 16(a0)
sd x19, 24(a0)
sd x20, 32(a0)
sd x21, 40(a0)
sd x22, 48(a0)
sd x23, 56(a0)
sd x24, 64(a0)
sd x25, 72(a0)
sd x26, 80(a0)
sd x27, 88(a0)
sd x28, 96(a0)
sd x29, 104(a0)
sd x30, 112(a0)
sd x31, 120(a0)
// adjust flags bit 5 -> bit 11
li x5, ~(1<<11)
and x8, x8, x5
andi x5, x8, 1<<5
slli x5, x5, 11-5
or x8, x8, x5
sd x8, 128(a0) //xFlags
sd x7, 136(a0) // put back reg value in emu, including EIP (so x7 must be EIP now)
// fallback to epilog_fast now, just restoring saved regs
rv64_epilog_fast:
ld sp, 808(a0) // restore saved sp from emu->xSPSave, see rv64_prolog
ld x9, -8(sp)
sd x9, 808(a0) // put back old value
ld ra, (sp) // save ra
ld x8, 8(sp) // save fp
ld x18, (2*8)(sp)
ld x19, (3*8)(sp)
ld x20, (4*8)(sp)
ld x21, (5*8)(sp)
ld x22, (6*8)(sp)
ld x23, (7*8)(sp)
ld x24, (8*8)(sp)
ld x25, (9*8)(sp)
ld x26, (10*8)(sp)
ld x27, (11*8)(sp)
ld x9, (12*8)(sp)
fld f18, (13*8)(sp)
fld f19, (14*8)(sp)
fld f20, (15*8)(sp)
fld f21, (16*8)(sp)
fld f22, (17*8)(sp)
fld f23, (19*8)(sp)
fld f24, (19*8)(sp)
fld f25, (20*8)(sp)
fld f26, (21*8)(sp)
fld f27, (22*8)(sp)
addi sp, sp, (8 * 24)
//end, return...
ret
|