Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
eb6c689
Bring throw helpers to PUSH_COOP_PINVOKE_FRAME plan
am11 Oct 26, 2025
5359b4c
Handle FP regs
am11 Jan 8, 2026
cbb9238
.
am11 Jan 8, 2026
b4a3ab2
wasm
am11 Jan 9, 2026
7df98b1
arm et al.
am11 Jan 9, 2026
14e1537
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 9, 2026
fef4204
Account for FP callee-saved regs
am11 Jan 9, 2026
4835a5f
.
am11 Jan 9, 2026
2746edf
.
am11 Jan 10, 2026
95c39e5
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 10, 2026
2450d88
fixes and reverts
am11 Jan 10, 2026
7fe9c53
[x64] unix: fix alignment, win: test a random thought
am11 Jan 11, 2026
bd342cf
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 11, 2026
e8287a5
linux-x64 fixes
am11 Jan 11, 2026
8e7a5ff
linux-x64
am11 Jan 11, 2026
9bb83b5
linux-arm32
am11 Jan 11, 2026
bf0e4c5
Revert
am11 Jan 12, 2026
af084b8
Switch to reusing PROLOG_WITH_TRANSITION_BLOCK
am11 Jan 12, 2026
17845a5
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 12, 2026
b5e6e6e
Revert "Switch to reusing PROLOG_WITH_TRANSITION_BLOCK"
am11 Jan 12, 2026
40313c1
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 12, 2026
0147c5c
Address RBP feedback
am11 Jan 12, 2026
22571b2
Prevent FP exceptions during JIT on AMD64 Windows
am11 Jan 12, 2026
fa44e1e
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 12, 2026
b109060
Remove obsolete comment (now that Init() is gone)
am11 Jan 12, 2026
dd15723
Enhance Context.asm with MXCSR reset explanation
am11 Jan 13, 2026
3c35b1b
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 13, 2026
d11f9fc
Address fb
am11 Jan 13, 2026
366421c
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 13, 2026
fbf03ab
Address fb
am11 Jan 13, 2026
c1146d4
.
am11 Jan 13, 2026
316d0a7
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 13, 2026
e918825
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 13, 2026
3cac3e0
Move MXCSR reset from PreStubWorker to CallEHFilterFunclet
am11 Jan 14, 2026
4309af3
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 14, 2026
b4d2eab
Fix FltSave initialization in UpdateContextFromTransitionBlock
am11 Jan 15, 2026
4317981
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 15, 2026
77c9ebb
Allocate shadow space for Windows x64 ABI calls
am11 Jan 15, 2026
7cb82b1
Address jkotas feedback and bring back ldmxcsr
am11 Jan 15, 2026
ee16162
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 15, 2026
d39d981
Remove MXCSR reset in Context.asm
am11 Jan 15, 2026
09f7e85
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 15, 2026
9275d5c
Remove MXCSR reset before managed code invocation
am11 Jan 15, 2026
a78797a
Cleanups fb
am11 Jan 16, 2026
49610d1
Merge branch 'main' into feature/il_throw_PUSH_COOP_PINVOKE_FRAME
am11 Jan 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/coreclr/pal/inc/unixasmmacrosamd64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,39 @@ C_FUNC(\Name\()_End):
POP_CALLEE_SAVED_REGISTERS
.endm

// Pushes a full TransitionBlock on the stack including argument registers and
// floating point argument registers. Used for exception throw helpers where we
// need to capture the complete register state.
//
// Stack layout (from high to low address after prologue):
// Return address
// CalleeSavedRegisters (rbp, rbx, r15, r14, r13, r12 - 48 bytes)
// ArgumentRegisters (r9, r8, rcx, rdx, rsi, rdi - 48 bytes) <- TransitionBlock
// Padding (16 bytes for 16-byte alignment)
// FloatArgumentRegisters (xmm0-xmm7, 128 bytes)
// sp points here
//
// Stack alignment: After call (8) + callee-saved (48) + arg regs (48) + alloc (144) + call (8) = 256 bytes
// 256 % 16 = 0, so stack is properly aligned for the call to IL_Throw_Impl.
//
// On exit, \target contains the TransitionBlock pointer (after float args area).
.macro PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS target
set_cfa_register rsp, 8

PUSH_CALLEE_SAVED_REGISTERS
PUSH_ARGUMENT_REGISTERS

// Allocate space for alignment (16 bytes) + float argument registers (128 bytes) = 144 bytes
alloc_stack 144
// Save float argument registers at offset 16 (after alignment padding)
// This ensures floats are at TransitionBlock - 128 (matching GetOffsetOfFloatArgumentRegisters)
SAVE_FLOAT_ARGUMENT_REGISTERS 16

END_PROLOGUE

lea \target, [rsp + 144]
.endm

.macro INLINE_GETTHREAD
// Inlined version of call C_FUNC(RhpGetThread)
INLINE_GET_TLS_VAR t_CurrentThreadInfo
Expand Down
36 changes: 36 additions & 0 deletions src/coreclr/pal/inc/unixasmmacrosarm.inc
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,42 @@ C_FUNC(\Name):
add \target, sp, 4
.endm

// Pushes a full TransitionBlock on the stack including float argument registers.
// On exit, \target contains the TransitionBlock pointer.
//
// Stack layout (from sp going up):
// sp+0: d8-d15 (64 bytes) - FP callee-saved
// sp+64: padding (4 bytes) - to make d0-d7 8-byte aligned at TransitionBlock-68
// sp+68: d0-d7 (64 bytes) - float argument registers (at TransitionBlock - 68)
// sp+132: padding (4 bytes) - to keep total allocation 8-byte aligned
// sp+136: TransitionBlock starts here (CalleeSavedRegisters + ArgumentRegisters pushed above)
//
// GetNegSpaceSize() for ARM32 = 64 (FloatArgumentRegisters) + 4 (padding) = 68
// GetOffsetOfFloatArgumentRegisters() = -68
//
// Total stack alloc: 64 + 4 + 64 + 4 = 136 bytes
// Stack: Arguments(16) + callee-saved(36) + alloc(136) = 188 bytes
// 188 % 4 = 0, properly aligned for ARM32
.macro PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS target
// Push argument registers (r0-r3) - these will be at highest address in TransitionBlock
PUSH_ARGUMENT_REGISTERS
PUSH_CALLEE_SAVED_REGISTERS
PROLOG_STACK_SAVE_OFFSET r7, #12
// let r7 point the saved r7 in the stack (clang FP style)
// Allocate space for: d8-d15 (64) + padding (4) + d0-d7 (64) + padding (4) = 136 bytes
alloc_stack 136
// Save floating point argument registers (d0-d7) at sp+68 (TransitionBlock - 68)
add r12, sp, #68
vstm r12, {d0-d7}
// Save FP callee-saved registers (d8-d15) at sp+0
add r12, sp, #0
vstm r12, {d8-d15}
CHECK_STACK_ALIGNMENT
END_PROLOGUE
// TransitionBlock is at sp + 136
add \target, sp, #136
.endm

.macro POP_COOP_PINVOKE_FRAME
free_stack 4
POP_CALLEE_SAVED_REGISTERS
Expand Down
49 changes: 48 additions & 1 deletion src/coreclr/pal/inc/unixasmmacrosarm64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,54 @@ C_FUNC(\Name\()_End):
EPILOG_RESTORE_REG_PAIR x25, x26, 64
EPILOG_RESTORE_REG_PAIR x27, x28, 80
EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176
.endm
.endm

// Pushes a full TransitionBlock on the stack including argument registers and
// floating point argument registers. Used for exception throw helpers where we
// need to capture the complete register state including FP callee-saved registers.
//
// Stack layout (from low to high address):
// sp+0: FP callee-saved registers (d8-d15, 64 bytes)
// sp+64: FloatArgumentRegisters (q0-q7, 128 bytes)
// sp+192: TransitionBlock start (176 bytes)
// - CalleeSavedRegisters (fp, lr, x19-x28 - 96 bytes)
// - padding (8 bytes)
// - x8 (8 bytes)
// - ArgumentRegisters (x0-x7, 64 bytes)
//
// On exit, \target contains the TransitionBlock pointer (sp+192).
.macro PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS target
PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -176

// Spill callee saved registers
PROLOG_SAVE_REG_PAIR x19, x20, 16
PROLOG_SAVE_REG_PAIR x21, x22, 32
PROLOG_SAVE_REG_PAIR x23, x24, 48
PROLOG_SAVE_REG_PAIR x25, x26, 64
PROLOG_SAVE_REG_PAIR x27, x28, 80

// Allocate space for FloatArgumentRegisters (128) + FP callee-saved (64) = 192 bytes
PROLOG_STACK_ALLOC 192

// Save argument registers (x8, x0-x7) at offset 296 from sp (192 + 104)
SAVE_ARGUMENT_REGISTERS sp, 296

// Save floating point argument registers (q0-q7) at sp+64
SAVE_FLOAT_ARGUMENT_REGISTERS sp, 64

// Save FP callee-saved registers (d8-d15) at sp+0
str d8, [sp, #0]
str d9, [sp, #8]
str d10, [sp, #16]
str d11, [sp, #24]
str d12, [sp, #32]
str d13, [sp, #40]
str d14, [sp, #48]
str d15, [sp, #56]

// Set target to TransitionBlock pointer
add \target, sp, #192
.endm

// ------------------------------------------------------------------
// Macro to generate Redirection Stubs
Expand Down
39 changes: 39 additions & 0 deletions src/coreclr/pal/inc/unixasmmacrosloongarch64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,45 @@ C_FUNC(\Name\()_End):
EPILOG_STACK_FREE 160
.endm

// Pushes a full TransitionBlock on the stack including argument registers and
// floating point argument registers. Used for exception throw helpers where we
// need to capture the complete register state.
//
// Stack layout (from low to high address):
// sp+0: FloatArgumentRegisters (fa0-fa7, 64 bytes)
// sp+64: TransitionBlock start
// - CalleeSavedRegisters (fp, ra, s0-s8 - 96 bytes)
// - ArgumentRegisters (a0-a7, 64 bytes)
//
// On exit, \target contains the TransitionBlock pointer (sp+128).
.macro PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS target
// Stack: FPCalleeSaved(64) + FloatArgs(64) + CalleeSaved(96) + Args(64) = 288 bytes
PROLOG_STACK_ALLOC 288
PROLOG_SAVE_REG_PAIR 22, 1, 128, 1

// Save callee-saved registers at offset 128 (after FP callee-saved and FloatArgumentRegisters)
SAVE_CALLEESAVED_REGISTERS $sp, 128

// Save argument registers (a0-a7) at offset 224
SAVE_ARGUMENT_REGISTERS $sp, 224

// Save floating-point argument registers (fa0-fa7) at offset 64
SAVE_FLOAT_ARGUMENT_REGISTERS $sp, 64

// Save FP callee-saved registers (f24-f31) at offset 0
fst.d $f24, $sp, 0
fst.d $f25, $sp, 8
fst.d $f26, $sp, 16
fst.d $f27, $sp, 24
fst.d $f28, $sp, 32
fst.d $f29, $sp, 40
fst.d $f30, $sp, 48
fst.d $f31, $sp, 56

// Set target to TransitionBlock pointer
addi.d \target, $sp, 128
.endm

// ------------------------------------------------------------------
// Macro to generate Redirection Stubs
//
Expand Down
45 changes: 45 additions & 0 deletions src/coreclr/pal/inc/unixasmmacrosriscv64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,51 @@ C_FUNC(\Name):
EPILOG_STACK_FREE 192
.endm

// Pushes a full TransitionBlock on the stack including argument registers and
// floating point argument registers. Used for exception throw helpers where we
// need to capture the complete register state.
//
// Stack layout (from low to high address):
// sp+0: FloatArgumentRegisters (fa0-fa7, 64 bytes)
// sp+64: TransitionBlock start
// - CalleeSavedRegisters (fp, ra, s1-s11, tp, gp - 120 bytes)
// - padding (8 bytes)
// - ArgumentRegisters (a0-a7, 64 bytes)
//
// On exit, \target contains the TransitionBlock pointer (sp+160).
.macro PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS target
// Stack: FPCalleeSaved(96) + FloatArgs(64) + CalleeSaved(120) + pad(8) + Args(64) = 352 bytes
PROLOG_STACK_ALLOC 352
PROLOG_SAVE_REG_PAIR fp, ra, 160, 1

// Save callee-saved registers at offset 160 (after FP callee-saved and FloatArgumentRegisters)
SAVE_CALLEESAVED_REGISTERS sp, 160

// Save argument registers (a0-a7) at offset 288
SAVE_ARGUMENT_REGISTERS sp, 288

// Save floating-point argument registers (fa0-fa7) at offset 96
SAVE_FLOAT_ARGUMENT_REGISTERS sp, 96

// Save FP callee-saved registers (fs0-fs11 = f8,f9,f18-f27) at offset 0
// RISC-V FP callee-saved: fs0=f8, fs1=f9, fs2-fs11=f18-f27
fsd fs0, 0(sp) // f8
fsd fs1, 8(sp) // f9
fsd fs2, 16(sp) // f18
fsd fs3, 24(sp) // f19
fsd fs4, 32(sp) // f20
fsd fs5, 40(sp) // f21
fsd fs6, 48(sp) // f22
fsd fs7, 56(sp) // f23
fsd fs8, 64(sp) // f24
fsd fs9, 72(sp) // f25
fsd fs10, 80(sp) // f26
fsd fs11, 88(sp) // f27

// Set target to TransitionBlock pointer
addi \target, sp, 160
.endm

// ------------------------------------------------------------------
// Macro to generate Redirection Stubs
//
Expand Down
50 changes: 50 additions & 0 deletions src/coreclr/vm/amd64/AsmHelpers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ extern ProfileLeave:proc
extern ProfileTailcall:proc
extern OnHijackWorker:proc
extern JIT_RareDisableHelperWorker:proc
extern IL_Throw_Impl:proc
extern IL_ThrowExact_Impl:proc
extern IL_Rethrow_Impl:proc
ifdef FEATURE_INTERPRETER
extern ExecuteInterpretedMethod:proc
extern GetInterpThreadContextWithPossiblyMissingThreadOrCallStub:proc
Expand Down Expand Up @@ -1200,4 +1203,51 @@ NESTED_END CallJittedMethodRetI8, _TEXT

endif ; FEATURE_INTERPRETER

;==========================================================================
; Capture a transition block with register values and call the IL_Throw_Impl
; implementation written in C.
;
; Input state:
; RCX = Pointer to exception object
;==========================================================================
NESTED_ENTRY IL_Throw, _TEXT
PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS rdx

; RCX already contains exception object
; RDX contains pointer to TransitionBlock
call IL_Throw_Impl
; Should never return
int 3
NESTED_END IL_Throw, _TEXT

;==========================================================================
; Capture a transition block with register values and call the IL_ThrowExact_Impl
; implementation written in C.
;
; Input state:
; RCX = Pointer to exception object
;==========================================================================
NESTED_ENTRY IL_ThrowExact, _TEXT
PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS rdx

; RCX already contains exception object
; RDX contains pointer to TransitionBlock
call IL_ThrowExact_Impl
; Should never return
int 3
NESTED_END IL_ThrowExact, _TEXT

;==========================================================================
; Capture a transition block with register values and call the IL_Rethrow_Impl
; implementation written in C.
;==========================================================================
NESTED_ENTRY IL_Rethrow, _TEXT
PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS rcx

; RCX contains pointer to TransitionBlock
call IL_Rethrow_Impl
; Should never return
int 3
NESTED_END IL_Rethrow, _TEXT

end
51 changes: 51 additions & 0 deletions src/coreclr/vm/amd64/AsmMacros.inc
Original file line number Diff line number Diff line change
Expand Up @@ -485,5 +485,56 @@ POP_COOP_PINVOKE_FRAME macro

endm

; Pushes a full TransitionBlock on the stack including argument registers and
; floating point argument registers. Used for exception throw helpers where we
; need to capture the complete register state including FP callee-saved registers.
;
; Stack layout (from high to low address after prologue):
; Return address (m_ReturnAddress)
; CalleeSavedRegisters (r15, r14, r13, r12, rbp, rbx, rsi, rdi - 64 bytes) <- TransitionBlock starts here
; Outgoing argument homes (32 bytes)
; FloatArgumentRegisters (xmm0-xmm3, 64 bytes)
; FP Callee-saved registers (xmm6-xmm15, 160 bytes)
; Padding (8 bytes for 16-byte alignment)
; sp points here
;
; Stack alignment: After call to IL_Throw (8 bytes) + callee-saved (64 bytes) + alloc (264 bytes) = 336 bytes
; The XMM save area at offset 8 is 16-byte aligned (336 - 8 = 328, 328 % 16 = 8, but RSP+8 % 16 = 0).
;
; On exit, target contains the TransitionBlock pointer (CalleeSavedRegisters).
PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS macro target

PUSH_CALLEE_SAVED_REGISTERS

; Allocate space for: outgoing args (32) + float args (64) + FP callee-saved (160) + padding (8) = 264 bytes
alloc_stack 264

; Save argument registers to shadow space area
; Shadow space is at offset 232 (after float args and FP callee-saved and padding) from sp
SAVE_ARGUMENT_REGISTERS 232

; Save float argument registers at offset 168 (after FP callee-saved and padding)
SAVE_FLOAT_ARGUMENT_REGISTERS 168

; Save FP callee-saved registers (xmm6-xmm15) at offset 8 (after padding)
; Offset 8 ensures 16-byte alignment for movaps
save_xmm128_postrsp xmm6, 8h
save_xmm128_postrsp xmm7, 18h
save_xmm128_postrsp xmm8, 28h
save_xmm128_postrsp xmm9, 38h
save_xmm128_postrsp xmm10, 48h
save_xmm128_postrsp xmm11, 58h
save_xmm128_postrsp xmm12, 68h
save_xmm128_postrsp xmm13, 78h
save_xmm128_postrsp xmm14, 88h
save_xmm128_postrsp xmm15, 98h

END_PROLOGUE

; TransitionBlock pointer points to CalleeSavedRegisters at rsp + 264
lea target, [rsp + 264]

endm

;; GC type flags
GC_ALLOC_FINALIZE equ 1
Loading
Loading