diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-04-04 20:32:23 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-04-04 21:40:34 -0700 |
| commit | 851fde879d85f3b76b42322f46cdc00c5f97e357 (patch) | |
| tree | e826806a24cc88268a9012b8c9361284c549b8a9 | |
| parent | 9310015c2584e254349388c0f4a97fcb2abd2b6f (diff) | |
| download | rust-851fde879d85f3b76b42322f46cdc00c5f97e357.tar.gz rust-851fde879d85f3b76b42322f46cdc00c5f97e357.zip | |
rt: Add architecture-specific general-purpose register definitions
This will be used for stack crawling, which in turn will be used for GC and unwinding.
| -rw-r--r-- | mk/rt.mk | 3 | ||||
| -rw-r--r-- | src/rt/arch/i386/gpr.cpp | 13 | ||||
| -rw-r--r-- | src/rt/arch/i386/gpr.h | 22 | ||||
| -rw-r--r-- | src/rt/arch/x86_64/gpr.cpp | 15 | ||||
| -rw-r--r-- | src/rt/arch/x86_64/gpr.h | 23 | ||||
| -rw-r--r-- | src/rt/rust_gpr_base.h | 24 |
6 files changed, 99 insertions, 1 deletions
diff --git a/mk/rt.mk b/mk/rt.mk index b24d98b40f8..af991f747b9 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -72,7 +72,8 @@ RUNTIME_CS_$(1) := \ rt/rust_box_annihilator.cpp \ rt/memory_region.cpp \ rt/boxed_region.cpp \ - rt/arch/$$(HOST_$(1))/context.cpp + rt/arch/$$(HOST_$(1))/context.cpp \ + rt/arch/$$(HOST_$(1))/gpr.cpp RUNTIME_S_$(1) := rt/arch/$$(HOST_$(1))/_context.S \ rt/arch/$$(HOST_$(1))/ccall.S \ diff --git a/src/rt/arch/i386/gpr.cpp b/src/rt/arch/i386/gpr.cpp new file mode 100644 index 00000000000..778d64490ba --- /dev/null +++ b/src/rt/arch/i386/gpr.cpp @@ -0,0 +1,13 @@ +#include "gpr.h" + +#define LOAD(rn) do { \ + uintptr_t tmp; \ + asm("movl %%" #rn ",%0" : "=r" (tmp) :); \ + this->rn = tmp; \ +} while (0) + +void rust_gpr::load() { + LOAD(eax); LOAD(ebx); LOAD(ecx); LOAD(edx); + LOAD(esi); LOAD(edi); LOAD(ebp); LOAD(esi); +} + diff --git a/src/rt/arch/i386/gpr.h b/src/rt/arch/i386/gpr.h new file mode 100644 index 00000000000..6c9685e2a5a --- /dev/null +++ b/src/rt/arch/i386/gpr.h @@ -0,0 +1,22 @@ +// General-purpose registers. This structure is used during stack crawling. + +#ifndef GPR_H +#define GPR_H + +#include "rust_gpr_base.h" + +class rust_gpr : public rust_gpr_base { +public: + uintptr_t eax, ebx, ecx, edx, esi, edi, ebp, eip; + + inline uintptr_t get_fp() { return ebp; } + inline uintptr_t get_ip() { return eip; } + + inline void set_fp(uintptr_t new_fp) { ebp = new_fp; } + inline void set_ip(uintptr_t new_ip) { eip = new_ip; } + + void load(); +}; + +#endif + diff --git a/src/rt/arch/x86_64/gpr.cpp b/src/rt/arch/x86_64/gpr.cpp new file mode 100644 index 00000000000..2533e826d4b --- /dev/null +++ b/src/rt/arch/x86_64/gpr.cpp @@ -0,0 +1,15 @@ +#include "gpr.h" + +#define LOAD(rn) do { \ + uintptr_t tmp; \ + asm("movq %%" #rn ",%0" : "=r" (tmp) :); \ + this->rn = tmp; \ +} while (0) + +void rust_gpr::load() { + LOAD(rax); LOAD(rbx); LOAD(rcx); LOAD(rdx); + LOAD(rsi); LOAD(rdi); LOAD(rbp); LOAD(rsi); + LOAD(r8); LOAD(r9); LOAD(r10); LOAD(r11); + LOAD(r12); LOAD(r13); LOAD(r14); LOAD(r15); +} + diff --git a/src/rt/arch/x86_64/gpr.h b/src/rt/arch/x86_64/gpr.h new file mode 100644 index 00000000000..620392c579f --- /dev/null +++ b/src/rt/arch/x86_64/gpr.h @@ -0,0 +1,23 @@ +// General-purpose registers. This structure is used during stack crawling. + +#ifndef GPR_H +#define GPR_H + +#include "rust_gpr_base.h" + +class rust_gpr : public rust_gpr_base { +public: + uintptr_t rax, rbx, rcx, rdx, rsi, rdi, rbp, rip; + uintptr_t r8, r9, r10, r11, r12, r13, r14, r15; + + inline uintptr_t get_fp() { return rbp; } + inline uintptr_t get_ip() { return rip; } + + inline void set_fp(uintptr_t new_fp) { rbp = new_fp; } + inline void set_ip(uintptr_t new_ip) { rip = new_ip; } + + void load(); +}; + +#endif + diff --git a/src/rt/rust_gpr_base.h b/src/rt/rust_gpr_base.h new file mode 100644 index 00000000000..d648800aae9 --- /dev/null +++ b/src/rt/rust_gpr_base.h @@ -0,0 +1,24 @@ +// Base class for architecture-specific general-purpose registers. This +// structure is used during stack crawling. + +#ifndef GPR_BASE_H +#define GPR_BASE_H + +#include <stdint.h> + +class rust_gpr_base { +public: + // Returns the value of a register by number. + inline uintptr_t &get(uint32_t i) { + return reinterpret_cast<uintptr_t *>(this)[i]; + } + + // Sets the value of a register by number. + inline void set(uint32_t i, uintptr_t val) { + reinterpret_cast<uintptr_t *>(this)[i] = val; + } +}; + + +#endif + |
