Skip to content

Commit abb348b

Browse files
author
Dan Cross
committed
x86_64: efficient segmentation register save
Be slightly more efficient about saving segmentation registers in traps. Instead of writing to memory twice (which probably doesn't _actually_ happen, but who knows?) instead copy to an intermediate register and then write to memory once. Signed-off-by: Dan Cross <[email protected]>
1 parent 8c416f4 commit abb348b

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

x86_64/src/trap.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,6 @@ pub unsafe extern "C" fn trap() -> ! {
124124
asm!(r#"
125125
// Allocate space to save registers.
126126
subq $((4 + 15) * 8), %rsp
127-
// Save the x86 segmentation registers.
128-
movq $0, 18*8(%rsp);
129-
movw %gs, 18*8(%rsp);
130-
movq $0, 17*8(%rsp);
131-
movw %fs, 17*8(%rsp);
132-
movq $0, 16*8(%rsp);
133-
movw %es, 16*8(%rsp);
134-
movq $0, 15*8(%rsp);
135-
movw %ds, 15*8(%rsp);
136127
// Save the general purpose registers.
137128
movq %r15, 14*8(%rsp);
138129
movq %r14, 13*8(%rsp);
@@ -149,6 +140,20 @@ pub unsafe extern "C" fn trap() -> ! {
149140
movq %rcx, 2*8(%rsp);
150141
movq %rbx, 1*8(%rsp);
151142
movq %rax, 0*8(%rsp);
143+
// Save the x86 segmentation registers. Uses %rdi
144+
// as a scratch register, so we do this after we've
145+
// saved the GP registers. Note that we clear %rdi
146+
// once, and then just move into the low bits and
147+
// copy to the stack.
148+
xorl %edi, %edi
149+
movw %gs, %di;
150+
movq %rdi, 18*8(%rsp);
151+
movw %fs, %di;
152+
movq %rdi, 17*8(%rsp);
153+
movw %es, %di;
154+
movq %rdi, 16*8(%rsp);
155+
movw %ds, %di;
156+
movq %rdi, 15*8(%rsp);
152157
// Fix up the vector number. We got into `trap` via a
153158
// CALL, so hardware pushed the address after after the
154159
// CALLQ instruction onto the stack, and the byte at that

0 commit comments

Comments
 (0)