Skip to content

Commit f91d734

Browse files
authored
closure: add ppc64 ELFv1 support (#26749)
* closure: add ppc64 ELFv1 support * add unsafe * native: ppc64 not supported yet
1 parent 048d0d9 commit f91d734

2 files changed

Lines changed: 52 additions & 7 deletions

File tree

‎vlib/builtin/closure/closure.c.v‎

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,20 @@ pub const closure_thunk = $if ppc64le {
108108
0x81, 0xc0, 0x40, 0x00, // jmp %g1
109109
0x01, 0x00, 0x00, 0x00 // nop
110110
]!
111+
} $else $if ppc64 {
112+
[
113+
u8(0x7C), 0x08, 0x02, 0xA6, // mflr %r0
114+
0x48, 0x00, 0x00, 0x05, // bl here
115+
0x7D, 0xC8, 0x02, 0xA6, // here: mflr %r14
116+
0x39, 0xCE, 0xC0, 0x08, // addi %r14, %r14, -16376
117+
0xC9, 0xCE, 0x00, 0x00, // lfd %f14, 0(%r14) // userdata
118+
0xE9, 0xCE, 0x00, 0x08, // ld %r14, 8(%r14) // func descriptor ptr
119+
0xE9, 0x8E, 0x00, 0x00, // ld %r12, 0(%r14) // code addr from descriptor
120+
0xE8, 0x4E, 0x00, 0x08, // ld %r2, 8(%r14) // TOC from descriptor
121+
0x7C, 0x08, 0x03, 0xA6, // mtlr %r0
122+
0x7D, 0x89, 0x03, 0xA6, // mtctr %r12
123+
0x4E, 0x80, 0x04, 0x20, // bctr
124+
]!
111125
} $else {
112126
[u8(0)]!
113127
}
@@ -167,6 +181,11 @@ const closure_get_data_bytes = $if arm32 {
167181
0x81, 0xc3, 0xe0, 0x08, // retl
168182
0x01, 0x00, 0x00, 0x00 // nop
169183
]!
184+
} $else $if ppc64 {
185+
[
186+
u8(0x7d), 0xc3, 0x00, 0x66, // mfvsrd %r3, %f14
187+
0x4e, 0x80, 0x00, 0x20 // blr
188+
]!
170189
} $else {
171190
[u8(0)]!
172191
}
@@ -223,11 +242,20 @@ fn closure_init() {
223242
closure_memory_protect_platform(g_closure.closure_ptr, page_size, .read_write)
224243
// Copy closure entry stub code
225244
vmemcpy(g_closure.closure_ptr, &closure_get_data_bytes[0], closure_get_data_bytes.len)
226-
// Re-enormalize execution protection
245+
// Re-normalize execution protection
227246
closure_memory_protect_platform(g_closure.closure_ptr, page_size, .read_exec)
228247
}
229248
// Setup global closure handler pointer
230-
g_closure.closure_get_data = g_closure.closure_ptr
249+
$if ppc64 {
250+
mut desc := unsafe { &voidptr(&u8(g_closure.closure_ptr) - assumed_page_size) }
251+
unsafe {
252+
desc[0] = g_closure.closure_ptr
253+
desc[1] = nil
254+
}
255+
g_closure.closure_get_data = desc
256+
} $else {
257+
g_closure.closure_get_data = g_closure.closure_ptr
258+
}
231259

232260
// Advance allocation pointer past header
233261
unsafe {
@@ -248,18 +276,35 @@ fn closure_create(func voidptr, data voidptr) voidptr {
248276
g_closure.closure_cap-- // Decrement slot counter
249277

250278
// Claim current closure slot
251-
mut curr_closure := g_closure.closure_ptr
279+
curr_closure := g_closure.closure_ptr
252280
unsafe {
253281
// Move to next available slot
254282
g_closure.closure_ptr = &u8(g_closure.closure_ptr) + closure_size
255283

256284
// Write closure metadata (data + function pointer)
257285
mut p := &voidptr(&u8(curr_closure) - assumed_page_size)
258-
p[0] = data // Stored closure context
259-
p[1] = func // Target function to execute
286+
$if ppc64 {
287+
// ELFv1: guard page layout per slot:
288+
// [0] desc[0] = thunk code address <- returned as ELFv1 function pointer
289+
// [1] desc[1] = nil (TOC unused; thunk loads real TOC from func descriptor)
290+
// [2] userdata
291+
// [3] func (V function descriptor pointer into .opd)
292+
p[0] = curr_closure
293+
p[1] = nil
294+
p[2] = data
295+
p[3] = func
296+
} $else {
297+
p[0] = data // Stored closure context
298+
p[1] = func // Target function to execute
299+
}
260300
}
261301
closure_mtx_unlock_platform()
262302

263303
// Return executable closure object
264-
return curr_closure
304+
$if ppc64 {
305+
// ELFv1: return descriptor address (guard page), not raw code address
306+
return unsafe { &u8(curr_closure) - assumed_page_size }
307+
} $else {
308+
return curr_closure
309+
}
265310
}

‎vlib/v/gen/native/comptime.v‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ fn (mut g Gen) comptime_ident(name string, is_comptime_option bool) bool {
170170
'x86', 'x32', 'i386', 'arm32', 'rv32' {
171171
false // native only supports 64-bit systems
172172
}
173-
'rv64', 's390x', 'ppc64le', 'loongarch64', 'sparc64' {
173+
'rv64', 's390x', 'ppc64le', 'loongarch64', 'sparc64', 'ppc64' {
174174
false // not support yet
175175
}
176176
'little_endian' {

0 commit comments

Comments
 (0)