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 doesn't define this alias in object.d, but Phobos (both 1 and 2)
25 * XXX: this (more general approach) doesn't work:
27 * static if (!is(string))
28 * private alias char[] string;
30 * See: http://d.puremagic.com/issues/show_bug.cgi?id=2848
33 private alias char[] string;
40 * Push the registers into the stack.
42 * Note that this function should be used as a string mixin because if
43 * a regular function call would be done, the stack would be unwound at
44 * function exit and the register will not longer be in the stack.
46 * A pointer to the top of the stack is stored in a variable with the name
47 * 'sp_name' (which is expected to be a void*).
50 * -----------------------------------------------------------------------
51 * void some_function()
54 * mixin(push_registers("sp"));
56 * mixin(pop_registers("sp"));
58 * -----------------------------------------------------------------------
60 * See_Also: pop_registers()
63 string push_registers(string sp_name);
66 * Pop the registers out the stack.
68 * Note that this function should be used as a string mixin (see
69 * push_registers() for more details).
71 * A pointer to the top of the stack can be obtained from a variable with
72 * the name 'sp_name' (which is expected to be a void*).
74 * See_Also: push_registers()
76 string pop_registers(string sp_name);
87 * GCC has an intrinsic function that does the job of pushing the
88 * registers into the stack, we use that function if available because it
89 * should work in all GCC supported architectures.
91 * Nothing needs to be done to pop the registers from the stack.
94 string push_registers(string sp_name)
97 __builtin_unwind_init();
98 " ~ sp_name ~ " = &" ~ sp_name ~ ";
102 string pop_registers(string sp_name)
112 * For X86 PUSHAD/POPAD are not used because they are too susceptible to
113 * compiler optimizations (like omitting the frame pointer).
115 * This method should work safely with all optimizations because it doesn't
116 * work behind the compilers back.
119 string push_registers(string sp_name)
122 size_t eax, ecx, edx, ebx, ebp, esi, edi;
132 mov " ~ sp_name ~ "[EBP], ESP;
137 string pop_registers(string sp_name)
143 else version (X86_64)
147 * See X86 comment above, X86_64 uses the same trick.
150 string push_registers(string sp_name)
153 size_t rax, rbx, rcx, rdx, rbp, rsi, rdi,
154 r10, r11, r12, r13, r14, r15;
170 movq " ~ sp_name ~ "[RBP], RSP;
175 string pop_registers(string sp_name)
181 else // Unknown compiler/architecture
184 static assert(false, "Don't know how to push registers into the stack "
185 "for this compiler/architecture");
189 // vim: set et sw=4 sts=4 :