Mercurial > pub > dyncall > dyncall
annotate dyncallback/dyncall_thunk_sparc64.c @ 620:14c582c828b9
- test/resolve_self: use a more portable linker option to export exec symbols (fixes some builds)
author | Tassilo Philipp |
---|---|
date | Mon, 03 Oct 2022 16:52:15 +0200 |
parents | 9d0eefb0e0f0 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dyncallback | |
5 File: dyncallback/dyncall_thunk_sparc64.c | |
6 Description: Thunk - Implementation for sparc64 | |
7 License: | |
8 | |
607
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
9 Copyright (c) 2007-2022 Daniel Adler <dadler@uni-goettingen.de>, |
0 | 10 Tassilo Philipp <tphilipp@potion-studios.com> |
11 | |
12 Permission to use, copy, modify, and distribute this software for any | |
13 purpose with or without fee is hereby granted, provided that the above | |
14 copyright notice and this permission notice appear in all copies. | |
15 | |
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
23 | |
24 */ | |
25 | |
26 | |
27 #include "dyncall_thunk.h" | |
28 | |
29 void dcbInitThunk(DCThunk* p, void (*entry)()) | |
30 { | |
189 | 31 /* example |
32 ; put thunk pointer in g1 | |
33 0: 03 00 00 00 sethi %hi(0), %g1 | |
34 4: 82 10 60 00 or %g1, 0, %g1 | |
35 8: 83 28 70 20 sllx %g1, 0x20, %g1 | |
607
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
36 |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
37 12: 21 00 00 00 sethi %hi(0), %g3 |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
38 16: a0 14 20 00 or %g3, 0, %g3 |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
39 20: 82 04 00 01 add %g3, %g1, %g1 |
189 | 40 ; use g2 for entry pointer and "call" it, b/c branch instructions can't handle 64bit addresses |
41 24: 05 00 00 00 sethi %hi(0), %g2 | |
42 28: 84 10 a0 00 or %g2, 0, %g2 | |
43 32: 85 28 b0 20 sllx %g2, 0x20, %g2 | |
607
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
44 |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
45 36: 21 00 00 00 sethi %hi(0), %g3 |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
46 40: a0 14 20 00 or %g3, 0, %g3 |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
47 44: 84 04 00 02 add %g3, %g2, %g2 |
189 | 48 ; jump - write link to %g0, effectively discarding it; also nop for delay slot |
49 48: 81 c0 80 00 jmpl %g2, %g0 | |
50 52: 01 00 00 00 nop | |
51 */ | |
52 | |
607
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
53 |
189 | 54 union { |
55 unsigned int x[2]; | |
56 void* p; | |
57 } t, e; | |
58 t.p = p; | |
59 e.p = entry; | |
60 | |
61 p->code[ 0] = 0x03000000 | (t.x[0] >> 10); /* sethi %hi(p), %g1 -- hi 22 bits */ | |
62 p->code[ 1] = 0x82106000 | (t.x[0] & 0x3ff); /* or %g1, <p&0x3ff>, %g1 -- lo 10 bits */ | |
63 p->code[ 2] = 0x83287020; /* sllx %g1, 0x20, %g1 */ | |
607
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
64 p->code[ 3] = 0x07000000 | (t.x[1] >> 10); /* sethi %hi(p), %g3 */ |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
65 p->code[ 4] = 0x8610e000 | (t.x[1] & 0x3ff); /* or %g3, <p&0x3ff>, %g3 */ |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
66 p->code[ 5] = 0x8200c001; /* add %g3, %g1, %g1 */ |
189 | 67 p->code[ 6] = 0x05000000 | (e.x[0] >> 10); /* sethi %hi(entry), %g2 */ |
68 p->code[ 7] = 0x8410a000 | (e.x[0] & 0x3ff); /* or %g2, <entry&0x3ff>, %g2 */ | |
69 p->code[ 8] = 0x8528b020; /* sllx %g2, 0x20, %g2 */ | |
607
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
70 p->code[ 9] = 0x07000000 | (e.x[1] >> 10); /* sethi %hi(entry), %g3 */ |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
71 p->code[10] = 0x8610e000 | (e.x[1] & 0x3ff); /* or %g3, <entry&0x3ff>, %g3 */ |
9d0eefb0e0f0
- sparc64 callback crash fix (local register wasn't preserved)
Tassilo Philipp
parents:
281
diff
changeset
|
72 p->code[11] = 0x8400c002; /* add %g3, %g2, %g2 */ |
189 | 73 p->code[12] = 0x81c08000; /* jmpl %g2, %g0 -- discards link addr */ |
74 p->code[13] = 0x01000000; /* nop */ | |
0 | 75 } |
76 |