2 * Architecture (and compiler) dependent functions.
4 * This is a support module for the Naive Garbage Collector. All the code that
5 * depends on the architecture (or compiler) is in this module.
8 * Copyright: Public Domain
9 * License: Public Domain
10 * Authors: Leandro Lucarella <llucax@gmail.com>
19 * Small hack to define the string alias if not defined
21 * Tango don't define this alias in object.d, but Phobos 1 and 2 does.
24 * XXX: this (more general approach) doesn't work:
26 * static if (!is(string))
27 * private alias char[] string;
29 * See: http://d.puremagic.com/issues/show_bug.cgi?id=2848
32 private alias char[] string;
39 * Push the registers into the stack.
41 * Note that this function should be used as a string mixin because if
42 * a regular function call would be done, the stack would be unwound at
43 * function exit and the register will not longer be in the stack.
45 * A pointer to the top of the stack is stored in a variable with the name
46 * 'sp_name' (which is expected to be a void*).
49 * -----------------------------------------------------------------------
50 * void some_function()
53 * mixin(push_registers("sp"));
55 * mixin(pop_registers("sp"));
57 * -----------------------------------------------------------------------
59 * See_Also: pop_registers()
62 string push_registers(string sp_name);
65 * Pop the registers out the stack.
67 * Note that this function should be used as a string mixin (see
68 * push_registers() for more details).
70 * A pointer to the top of the stack can be obtained from a variable with
71 * the name 'sp_name' (which is expected to be a void*).
73 * See_Also: push_registers()
75 string pop_registers(string sp_name);
86 * GCC has an intrinsic function that does the job of pushing the
87 * registers into the stack, we use that function if available because it
88 * should work in all GCC supported architectures.
90 * Nothing needs to be done to pop the registers from the stack.
93 string push_registers(string sp_name)
96 __builtin_unwind_init();
97 " ~ sp_name ~ " = &" ~ sp_name ~ ";
101 string pop_registers(string sp_name)
111 * For X86 PUSHAD/POPAD are not used because they are too susceptible to
112 * compiler optimizations (like omitting the frame pointer).
114 * This method should work safely with all optimizations because it doesn't
115 * work behind the compilers back.
118 string push_registers(string sp_name)
121 size_t eax, ecx, edx, ebx, ebp, esi, edi;
131 mov " ~ sp_name ~ "[EBP], ESP;
136 string pop_registers(string sp_name)
142 else version (X86_64)
146 * See X86 comment above, X86_64 uses the same trick.
149 string push_registers(string sp_name)
152 size_t rax, rbx, rcx, rdx, rbp, rsi, rdi,
153 r10, r11, r12, r13, r14, r15;
169 movq " ~ sp_name ~ "[RBP], RSP;
174 string pop_registers(string sp_name)
180 else // Unknown compiler/architecture
183 static assert(false, "Don't know how to push registers into the stack "
184 "for this compiler/architecture");
188 // vim: set et sw=4 sts=4 :