Skip to content

Commit cffcf6a

Browse files
committed
Trace uint64 mixed-width FFI pairs
1 parent 0fd94dd commit cffcf6a

7 files changed

Lines changed: 340 additions & 6 deletions

File tree

notes/ffi-ccall-jit-trampoline.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ with the helper signature preserving signedness for each argument. The first
1616
pointer returns, plus exact two-argument `pointer,int64_t` and
1717
`pointer,uint64_t` span-style calls and exact `int32_t,int64_t` /
1818
`int32_t,uint64_t` calls for those same return families. Exact
19-
`uint32_t,int64_t`, `uint32_t,uint64_t`, `int64_t,int32_t`, and
20-
`int64_t,uint32_t` pairs are covered too. The FPR subset accepts 0, 1, or 2
21-
same-kind exact float or double arguments. The first
19+
`uint32_t,int64_t`, `uint32_t,uint64_t`, `int64_t,int32_t`,
20+
`int64_t,uint32_t`, `uint64_t,int32_t`, and `uint64_t,uint32_t` pairs are
21+
covered too. The FPR subset accepts 0, 1, or 2 same-kind exact float or double
22+
arguments. The first
2223
mixed one-argument subset
2324
accepts exact `double(int32_t)`, `double(pointer)`, `double(float)`,
2425
`int32_t(double)`, `int32_t(float)`, `int32_t(int8_t)`, `pointer(double)`,
@@ -106,6 +107,8 @@ The scope is deliberately narrow:
106107
same return families;
107108
- exact two-argument `int64_t,int32_t` and `int64_t,uint32_t` calls for the
108109
same return families;
110+
- exact two-argument `uint64_t,int32_t` and `uint64_t,uint32_t` calls for the
111+
same return families;
109112
- same-kind exact float/double arguments and exact float/double returns;
110113
- exact one-argument `double(int32_t)`, `double(pointer)`, `double(float)`,
111114
`int32_t(double)`, `int32_t(float)`, `int32_t(int8_t)`,

notes/m7.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,9 +1618,10 @@ FFI C-call JIT trampoline:
16181618
`uint32_t,uint64_t` calls now record for those families too, covering
16191619
unsigned-id/signed-offset and unsigned-id/unsigned-size helper shapes. Exact
16201620
`int64_t,int32_t` and `int64_t,uint32_t` calls now record for those families
1621-
as the first signed-64-first mixed-width pairs; other two-argument 64-bit GPR
1622-
combinations remain on the interpreted native path until the wider signature
1623-
matrix is added.
1621+
as the first signed-64-first mixed-width pairs, and exact
1622+
`uint64_t,int32_t` and `uint64_t,uint32_t` calls now cover the corresponding
1623+
unsigned-64-first pairs; other two-argument 64-bit GPR combinations remain
1624+
on the interpreted native path until the wider signature matrix is added.
16241625
Exact `int64_t(int32_t, void *, uint64_t)` calls now record through
16251626
`lj_ccall_jit_i64_i32_ptr_u64()`, covering the GPR ABI class used by
16261627
POSIX-style `ssize_t write(int, void *, size_t)` calls without enabling broad

src/lj_ccall.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,13 @@ void lj_ccall_jit_void_gpr(lua_State *L, void *func, uintptr_t a,
13981398
((void (*)(int64_t, uint32_t))(uintptr_t)func)
13991399
((int64_t)a, (uint32_t)b);
14001400
break;
1401+
case LJ_CCALL_JIT_SIG_U64_I32:
1402+
((void (*)(uint64_t, int32_t))(uintptr_t)func)((uint64_t)a, (int32_t)b);
1403+
break;
1404+
case LJ_CCALL_JIT_SIG_U64_U32:
1405+
((void (*)(uint64_t, uint32_t))(uintptr_t)func)
1406+
((uint64_t)a, (uint32_t)b);
1407+
break;
14011408
default:
14021409
break;
14031410
}
@@ -1501,6 +1508,14 @@ int32_t lj_ccall_jit_i32_gpr(lua_State *L, void *func, uintptr_t a,
15011508
ret = ((int32_t (*)(int64_t, uint32_t))(uintptr_t)func)
15021509
((int64_t)a, (uint32_t)b);
15031510
break;
1511+
case LJ_CCALL_JIT_SIG_U64_I32:
1512+
ret = ((int32_t (*)(uint64_t, int32_t))(uintptr_t)func)
1513+
((uint64_t)a, (int32_t)b);
1514+
break;
1515+
case LJ_CCALL_JIT_SIG_U64_U32:
1516+
ret = ((int32_t (*)(uint64_t, uint32_t))(uintptr_t)func)
1517+
((uint64_t)a, (uint32_t)b);
1518+
break;
15041519
default:
15051520
ret = 0;
15061521
break;
@@ -1649,6 +1664,14 @@ int32_t lj_ccall_jit_narrow_gpr(lua_State *L, void *func, uintptr_t a,
16491664
ret = (int32_t)((T (*)(int64_t, uint32_t))(uintptr_t)func) \
16501665
((int64_t)a, (uint32_t)b); \
16511666
break; \
1667+
case LJ_CCALL_JIT_SIG_U64_I32: \
1668+
ret = (int32_t)((T (*)(uint64_t, int32_t))(uintptr_t)func) \
1669+
((uint64_t)a, (int32_t)b); \
1670+
break; \
1671+
case LJ_CCALL_JIT_SIG_U64_U32: \
1672+
ret = (int32_t)((T (*)(uint64_t, uint32_t))(uintptr_t)func) \
1673+
((uint64_t)a, (uint32_t)b); \
1674+
break; \
16521675
default: \
16531676
ret = 0; \
16541677
break; \
@@ -1773,6 +1796,14 @@ double lj_ccall_jit_u32_gpr(lua_State *L, void *func, uintptr_t a,
17731796
ret = ((uint32_t (*)(int64_t, uint32_t))(uintptr_t)func)
17741797
((int64_t)a, (uint32_t)b);
17751798
break;
1799+
case LJ_CCALL_JIT_SIG_U64_I32:
1800+
ret = ((uint32_t (*)(uint64_t, int32_t))(uintptr_t)func)
1801+
((uint64_t)a, (int32_t)b);
1802+
break;
1803+
case LJ_CCALL_JIT_SIG_U64_U32:
1804+
ret = ((uint32_t (*)(uint64_t, uint32_t))(uintptr_t)func)
1805+
((uint64_t)a, (uint32_t)b);
1806+
break;
17761807
default:
17771808
ret = 0;
17781809
break;
@@ -2001,6 +2032,14 @@ int64_t lj_ccall_jit_i64_ret_gpr(lua_State *L, void *func, uintptr_t a,
20012032
ret = ((int64_t (*)(int64_t, uint32_t))(uintptr_t)func)
20022033
((int64_t)a, (uint32_t)b);
20032034
break;
2035+
case LJ_CCALL_JIT_SIG_U64_I32:
2036+
ret = ((int64_t (*)(uint64_t, int32_t))(uintptr_t)func)
2037+
((uint64_t)a, (int32_t)b);
2038+
break;
2039+
case LJ_CCALL_JIT_SIG_U64_U32:
2040+
ret = ((int64_t (*)(uint64_t, uint32_t))(uintptr_t)func)
2041+
((uint64_t)a, (uint32_t)b);
2042+
break;
20042043
default:
20052044
ret = 0;
20062045
break;
@@ -2106,6 +2145,14 @@ uint64_t lj_ccall_jit_u64_gpr(lua_State *L, void *func, uintptr_t a,
21062145
ret = ((uint64_t (*)(int64_t, uint32_t))(uintptr_t)func)
21072146
((int64_t)a, (uint32_t)b);
21082147
break;
2148+
case LJ_CCALL_JIT_SIG_U64_I32:
2149+
ret = ((uint64_t (*)(uint64_t, int32_t))(uintptr_t)func)
2150+
((uint64_t)a, (int32_t)b);
2151+
break;
2152+
case LJ_CCALL_JIT_SIG_U64_U32:
2153+
ret = ((uint64_t (*)(uint64_t, uint32_t))(uintptr_t)func)
2154+
((uint64_t)a, (uint32_t)b);
2155+
break;
21092156
default:
21102157
ret = 0;
21112158
break;
@@ -2211,6 +2258,14 @@ void *lj_ccall_jit_ptr_gpr(lua_State *L, void *func, uintptr_t a,
22112258
ret = ((void *(*)(int64_t, uint32_t))(uintptr_t)func)
22122259
((int64_t)a, (uint32_t)b);
22132260
break;
2261+
case LJ_CCALL_JIT_SIG_U64_I32:
2262+
ret = ((void *(*)(uint64_t, int32_t))(uintptr_t)func)
2263+
((uint64_t)a, (int32_t)b);
2264+
break;
2265+
case LJ_CCALL_JIT_SIG_U64_U32:
2266+
ret = ((void *(*)(uint64_t, uint32_t))(uintptr_t)func)
2267+
((uint64_t)a, (uint32_t)b);
2268+
break;
22142269
default:
22152270
ret = NULL;
22162271
break;

src/lj_ccall.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ typedef struct CCallNativeState {
221221
#define LJ_CCALL_JIT_SIG_U32_U64 20u
222222
#define LJ_CCALL_JIT_SIG_I64_I32 21u
223223
#define LJ_CCALL_JIT_SIG_I64_U32 22u
224+
#define LJ_CCALL_JIT_SIG_U64_I32 23u
225+
#define LJ_CCALL_JIT_SIG_U64_U32 24u
224226

225227
#define LJ_CCALL_JIT_NUM_SIG0 0u
226228
#define LJ_CCALL_JIT_NUM_SIG_NUM 1u

src/lj_crecord.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4006,6 +4006,12 @@ static uint32_t crec_call_jit_sig(MSize narg, const int *kind)
40064006
if (kind[0] == CREC_CALL_JIT_KIND_I64 &&
40074007
kind[1] == CREC_CALL_JIT_KIND_U32)
40084008
return LJ_CCALL_JIT_SIG_I64_U32;
4009+
if (kind[0] == CREC_CALL_JIT_KIND_U64 &&
4010+
kind[1] == CREC_CALL_JIT_KIND_I32)
4011+
return LJ_CCALL_JIT_SIG_U64_I32;
4012+
if (kind[0] == CREC_CALL_JIT_KIND_U64 &&
4013+
kind[1] == CREC_CALL_JIT_KIND_U32)
4014+
return LJ_CCALL_JIT_SIG_U64_U32;
40094015
if (kind[0] > CREC_CALL_JIT_KIND_PTR || kind[1] > CREC_CALL_JIT_KIND_PTR)
40104016
return UINT32_MAX;
40114017
return LJ_CCALL_JIT_SIG_I32_I32 +

tests/t-ffi-ccall-jit-lib.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,84 @@ uint64_t lj_m7_ccall_jit_u64_i64_u32(int64_t a, uint32_t b)
404404
((uint64_t)a & UINT64_C(1023)) + (uint64_t)(b & 1023u);
405405
}
406406

407+
uint8_t lj_m7_ccall_jit_u8_u64_i32(uint64_t a, int32_t b)
408+
{
409+
return (uint8_t)((a & UINT64_C(255)) + (uint32_t)b);
410+
}
411+
412+
uint8_t lj_m7_ccall_jit_u8_u64_u32(uint64_t a, uint32_t b)
413+
{
414+
return (uint8_t)((a & UINT64_C(255)) + (b & 255u));
415+
}
416+
417+
void lj_m7_ccall_jit_void_u64_i32(uint64_t a, int32_t b)
418+
{
419+
lj_m7_ccall_jit_void_count += (int)(a & UINT64_C(15)) + (int)(b & 15);
420+
}
421+
422+
void lj_m7_ccall_jit_void_u64_u32(uint64_t a, uint32_t b)
423+
{
424+
lj_m7_ccall_jit_void_count += (int)(a & UINT64_C(15)) + (int)(b & 15u);
425+
}
426+
427+
int32_t lj_m7_ccall_jit_i32_u64_i32(uint64_t a, int32_t b)
428+
{
429+
return (int32_t)((a & UINT64_C(1023)) + (uint32_t)b);
430+
}
431+
432+
int32_t lj_m7_ccall_jit_i32_u64_u32(uint64_t a, uint32_t b)
433+
{
434+
return (int32_t)((a & UINT64_C(1023)) + (b & 1023u));
435+
}
436+
437+
uint32_t lj_m7_ccall_jit_u32_u64_i32(uint64_t a, int32_t b)
438+
{
439+
return UINT32_C(0xf0000000) + (uint32_t)(a & UINT64_C(1023)) +
440+
(uint32_t)b;
441+
}
442+
443+
uint32_t lj_m7_ccall_jit_u32_u64_u32(uint64_t a, uint32_t b)
444+
{
445+
return UINT32_C(0xf0000000) + (uint32_t)(a & UINT64_C(1023)) +
446+
(b & 1023u);
447+
}
448+
449+
int *lj_m7_ccall_jit_ptr_u64_i32(uint64_t a, int32_t b)
450+
{
451+
return lj_m7_ccall_jit_values +
452+
(((uint32_t)(a & UINT64_C(3)) + (uint32_t)b) % 4u);
453+
}
454+
455+
int *lj_m7_ccall_jit_ptr_u64_u32(uint64_t a, uint32_t b)
456+
{
457+
return lj_m7_ccall_jit_values +
458+
(((uint32_t)(a & UINT64_C(3)) + (b & 3u)) % 4u);
459+
}
460+
461+
int64_t lj_m7_ccall_jit_i64_u64_i32(uint64_t a, int32_t b)
462+
{
463+
return INT64_C(0x100000000) + (int64_t)(a & UINT64_C(1023)) +
464+
(int64_t)b;
465+
}
466+
467+
int64_t lj_m7_ccall_jit_i64_u64_u32(uint64_t a, uint32_t b)
468+
{
469+
return INT64_C(0x100000000) + (int64_t)(a & UINT64_C(1023)) +
470+
(int64_t)(b & 1023u);
471+
}
472+
473+
uint64_t lj_m7_ccall_jit_u64_u64_i32(uint64_t a, int32_t b)
474+
{
475+
return UINT64_C(0x100000000) + (a & UINT64_C(1023)) +
476+
(uint64_t)(uint32_t)b;
477+
}
478+
479+
uint64_t lj_m7_ccall_jit_u64_u64_u32(uint64_t a, uint32_t b)
480+
{
481+
return UINT64_C(0x100000000) + (a & UINT64_C(1023)) +
482+
(uint64_t)(b & 1023u);
483+
}
484+
407485
int *lj_m7_ccall_jit_ptr_u32(uint32_t a)
408486
{
409487
return lj_m7_ccall_jit_values + (a & 3u);

0 commit comments

Comments
 (0)