@@ -403,9 +403,9 @@ X64ThunkEmitter::X64ThunkEmitter(X64Backend* backend, XbyakAllocator* allocator)
403403X64ThunkEmitter::~X64ThunkEmitter () {}
404404
405405HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk () {
406- // rcx = target
407- // rdx = arg0 (context)
408- // r8 = arg1 (guest return address)
406+ // rcx (win), rdi (linux) = target
407+ // rdx (win), rsi (linux) = arg0 (context)
408+ // r8 (win), rdx (linux) = arg1 (guest return address)
409409
410410 struct _code_offsets {
411411 size_t prolog;
@@ -420,9 +420,15 @@ HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
420420 code_offsets.prolog = getSize ();
421421
422422 // rsp + 0 = return address
423+ #if XE_PLATFORM_LINUX
424+ mov (qword[rsp + 8 * 3 ], rdx);
425+ mov (qword[rsp + 8 * 2 ], rsi);
426+ mov (qword[rsp + 8 * 1 ], rdi);
427+ #else
423428 mov (qword[rsp + 8 * 3 ], r8);
424429 mov (qword[rsp + 8 * 2 ], rdx);
425430 mov (qword[rsp + 8 * 1 ], rcx);
431+ #endif
426432 sub (rsp, stack_size);
427433
428434 code_offsets.prolog_stack_alloc = getSize ();
@@ -431,19 +437,31 @@ HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
431437 // Save nonvolatile registers.
432438 EmitSaveNonvolatileRegs ();
433439
440+ #ifdef XE_PLATFORM_LINUX
441+ mov (rax, rdi);
442+ // context already in rsi
443+ mov (rcx, rdx); // return address
444+ #else
434445 mov (rax, rcx);
435446 mov (rsi, rdx); // context
436447 mov (rcx, r8); // return address
448+ #endif
437449 call (rax);
438450
439451 EmitLoadNonvolatileRegs ();
440452
441453 code_offsets.epilog = getSize ();
442454
443455 add (rsp, stack_size);
456+ #if XE_PLATFORM_LINUX
457+ mov (rdi, qword[rsp + 8 * 1 ]);
458+ mov (rsi, qword[rsp + 8 * 2 ]);
459+ mov (rdx, qword[rsp + 8 * 3 ]);
460+ #else
444461 mov (rcx, qword[rsp + 8 * 1 ]);
445462 mov (rdx, qword[rsp + 8 * 2 ]);
446463 mov (r8, qword[rsp + 8 * 3 ]);
464+ #endif
447465 ret ();
448466
449467 code_offsets.tail = getSize ();
@@ -464,10 +482,12 @@ HostToGuestThunk X64ThunkEmitter::EmitHostToGuestThunk() {
464482}
465483
466484GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk () {
467- // rcx = target function
468- // rdx = arg0
469- // r8 = arg1
470- // r9 = arg2
485+ // rcx (windows), rdi (linux) = target function
486+ // rdx (windows), rsi (linux) = arg0
487+ // r8 (windows), rdx (linux) = arg1
488+ // r9 (windows), rcx (linux) = arg2
489+ // --- (windows), r8 (linux) = arg3
490+ // --- (windows), r9 (linux) = arg4
471491
472492 struct _code_offsets {
473493 size_t prolog;
@@ -490,8 +510,13 @@ GuestToHostThunk X64ThunkEmitter::EmitGuestToHostThunk() {
490510 // Save off volatile registers.
491511 EmitSaveVolatileRegs ();
492512
493- mov (rax, rcx); // function
513+ mov (rax, rcx); // function
514+ #if XE_PLATFORM_LINUX
515+ mov (rdi, GetContextReg ()); // context
516+ mov (rsi, rbx);
517+ #else
494518 mov (rcx, GetContextReg ()); // context
519+ #endif
495520 call (rax);
496521
497522 EmitLoadVolatileRegs ();
@@ -546,8 +571,13 @@ ResolveFunctionThunk X64ThunkEmitter::EmitResolveFunctionThunk() {
546571 // Save volatile registers
547572 EmitSaveVolatileRegs ();
548573
549- mov (rcx, rsi); // context
574+ #if XE_PLATFORM_LINUX
575+ mov (rdi, rsi); // context
576+ mov (rsi, rbx);
577+ #else
578+ mov (rcx, rsi); // context
550579 mov (rdx, rbx);
580+ #endif
551581 mov (rax, uint64_t (&ResolveFunction));
552582 call (rax);
553583
0 commit comments