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.
This commit is contained in:
Patrick Walton 2012-04-04 20:32:23 -07:00
parent 9310015c25
commit 851fde879d
6 changed files with 99 additions and 1 deletions

View File

@ -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 \

13
src/rt/arch/i386/gpr.cpp Normal file
View File

@ -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);
}

22
src/rt/arch/i386/gpr.h Normal file
View File

@ -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

View File

@ -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);
}

23
src/rt/arch/x86_64/gpr.h Normal file
View File

@ -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

24
src/rt/rust_gpr_base.h Normal file
View File

@ -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