about summary refs log tree commit diff
path: root/src/rt/arch
diff options
context:
space:
mode:
authorkyeongwoon <kyeongwoon.lee@samsung.com>2012-11-30 09:21:49 +0900
committerBrian Anderson <banderson@mozilla.com>2013-01-13 16:43:39 -0800
commit987f824f233faee4aed39dac92a1b442d42965cc (patch)
tree2cf1b078738e9bf580b9ee43f674d95c403751fa /src/rt/arch
parent27e6a0fa5651dbda55773488c8b706adfa5cefc2 (diff)
downloadrust-987f824f233faee4aed39dac92a1b442d42965cc.tar.gz
rust-987f824f233faee4aed39dac92a1b442d42965cc.zip
Support ARM and Android
Conflicts:
	src/libcore/os.rs
	src/librustc/back/link.rs
	src/librustc/driver/driver.rs
	src/librustc/metadata/loader.rs
	src/librustc/middle/trans/base.rs
Diffstat (limited to 'src/rt/arch')
-rw-r--r--src/rt/arch/arm/_context.S47
-rw-r--r--src/rt/arch/arm/ccall.S27
-rw-r--r--src/rt/arch/arm/context.cpp36
-rw-r--r--src/rt/arch/arm/context.h43
-rw-r--r--src/rt/arch/arm/gpr.cpp15
-rw-r--r--src/rt/arch/arm/gpr.h23
-rw-r--r--src/rt/arch/arm/record_sp.S61
-rw-r--r--src/rt/arch/arm/regs.h21
8 files changed, 273 insertions, 0 deletions
diff --git a/src/rt/arch/arm/_context.S b/src/rt/arch/arm/_context.S
new file mode 100644
index 00000000000..8d370c2d64e
--- /dev/null
+++ b/src/rt/arch/arm/_context.S
@@ -0,0 +1,47 @@
+.text
+.code 32
+.arm
+.align
+
+
+.globl swap_registers
+swap_registers:
+	str r0, [r0, #0]
+	str r3, [r0, #12]
+	str r4, [r0, #16]
+	str r5, [r0, #20]
+	str r6, [r0, #24]
+	str r7, [r0, #28]
+	str r8, [r0, #32]
+	str r9, [r0, #36]
+	str r10, [r0, #40]
+	str r11, [r0, #44]
+	str r12, [r0, #48]
+	str sp, [r0, #52] 
+	str lr, [r0, #56]
+
+	mrs r2, cpsr
+	str r2, [r0, #64]
+	
+
+	ldr r0, [r1, #0]
+	ldr r3, [r1, #12]
+	ldr r4, [r1, #16]
+	ldr r5, [r1, #20]
+	ldr r6, [r1, #24]
+	ldr r7, [r1, #28]
+	ldr r8, [r1, #32]
+	ldr r9, [r1, #36]
+	ldr r10, [r1, #40]
+	ldr r11, [r1, #44]
+	ldr r12, [r1, #48]
+	
+	ldr sp, [r1, #52]
+	ldr lr, [r1, #56]
+	 
+	ldr r2, [r1, #64]
+	msr cpsr_cxsf, r2
+
+	mov pc, lr
+
+
diff --git a/src/rt/arch/arm/ccall.S b/src/rt/arch/arm/ccall.S
new file mode 100644
index 00000000000..4b89cc994a7
--- /dev/null
+++ b/src/rt/arch/arm/ccall.S
@@ -0,0 +1,27 @@
+.text
+.code 32
+.arm
+.align
+
+.globl __morestack
+.hidden __morestack
+__morestack:
+	mov r3, sp
+	mov sp, r2
+	
+	str r3, [sp]
+	str lr, [sp, #-4]
+	
+	sub sp, #8
+	
+	blx r1
+
+	add sp, #8
+	
+	ldr lr, [sp, #-4]
+	ldr r3, [sp] 
+	
+	mov sp, r3
+	mov pc, lr
+	
+
diff --git a/src/rt/arch/arm/context.cpp b/src/rt/arch/arm/context.cpp
new file mode 100644
index 00000000000..dbf06a532a8
--- /dev/null
+++ b/src/rt/arch/arm/context.cpp
@@ -0,0 +1,36 @@
+
+#include "context.h"
+#include "../../rust_globals.h"
+
+extern "C" void CDECL swap_registers(registers_t *oregs,
+                                     registers_t *regs)
+asm ("swap_registers");
+
+context::context()
+{
+    assert((void*)&regs == (void*)this);
+    memset(&regs, 0, sizeof(regs));
+}
+
+void context::swap(context &out)
+{
+    swap_registers(&out.regs, &regs);
+}
+
+void context::call(void *f, void *arg, void *stack)
+{
+  // Get the current context, which we will then modify to call the
+  // given function.
+  swap(*this);
+
+  // set up the stack
+  uint32_t *sp = ( uint32_t *)stack;
+  //sp = align_down(sp);
+  // The final return address. 0 indicates the bottom of the stack
+  *--sp = 0;
+
+  regs.data[0] = ( uint32_t )arg; // r0
+  regs.data[13] = ( uint32_t )sp; //#52 sp, r13
+  regs.data[14] = ( uint32_t )f;  //#60 pc, r15 --> lr,
+  // Last base pointer on the stack should be 0
+}
diff --git a/src/rt/arch/arm/context.h b/src/rt/arch/arm/context.h
new file mode 100644
index 00000000000..6c7db766d6a
--- /dev/null
+++ b/src/rt/arch/arm/context.h
@@ -0,0 +1,43 @@
+// -*- mode: c++ -*-
+
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+#include <cstdlib>
+#include <inttypes.h>
+#include <stdint.h>
+//#include <xmmintrin.h>
+
+#include "vg/memcheck.h"
+
+template<typename T>
+T align_down(T sp)
+{
+    // There is no platform we care about that needs more than a
+    // 16-byte alignment.
+    return (T)((uint32_t)sp & ~(16 - 1));
+}
+
+// The struct in which we store the saved data.  This is mostly the
+// volatile registers and instruction pointer, but it also includes
+// RCX/RDI which are used to pass arguments.  The indices for each
+// register are found in "regs.h".  Note that the alignment must be
+// 16 bytes so that SSE instructions can be used.
+#include "regs.h"
+struct registers_t {
+    uint32_t data[RUSTRT_MAX];
+} __attribute__((aligned(16)));
+
+class context {
+public:
+    registers_t regs;
+
+    context();
+
+    context *next;
+
+    void swap(context &out);
+    void call(void *f, void *arg, void *sp);
+};
+
+#endif
diff --git a/src/rt/arch/arm/gpr.cpp b/src/rt/arch/arm/gpr.cpp
new file mode 100644
index 00000000000..32a68d0732a
--- /dev/null
+++ b/src/rt/arch/arm/gpr.cpp
@@ -0,0 +1,15 @@
+#include "gpr.h"
+
+#define LOAD(rn) do { \
+    uintptr_t tmp; \
+    asm("mov %%" #rn ",%0" : "=r" (tmp) :); \
+    this->rn = tmp; \
+} while (0)
+
+void rust_gpr::load() {
+    LOAD(r0); LOAD(r1); LOAD(r2); LOAD(r3);
+    LOAD(r4); LOAD(r5); LOAD(r6); LOAD(r7);
+    LOAD(r8);  LOAD(r9);  LOAD(r10); LOAD(r11);
+    LOAD(r12); LOAD(r13); LOAD(r14); LOAD(r15);
+}
+
diff --git a/src/rt/arch/arm/gpr.h b/src/rt/arch/arm/gpr.h
new file mode 100644
index 00000000000..472c8a05e35
--- /dev/null
+++ b/src/rt/arch/arm/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 r0, r1, r2, r3, r4, r5, r6, r7;
+    uintptr_t  r8,  r9, r10, r11, r12, r13, r14, r15;
+
+    inline uintptr_t get_fp() { return r11; }
+    inline uintptr_t get_ip() { return r12; }
+
+    inline void set_fp(uintptr_t new_fp) { r11 = new_fp; }
+    inline void set_ip(uintptr_t new_ip) { r12 = new_ip; }
+
+    void load();
+};
+
+#endif
+
diff --git a/src/rt/arch/arm/record_sp.S b/src/rt/arch/arm/record_sp.S
new file mode 100644
index 00000000000..193104d53b1
--- /dev/null
+++ b/src/rt/arch/arm/record_sp.S
@@ -0,0 +1,61 @@
+.text
+.code 32
+.arm
+.align
+
+
+.globl record_sp_limit
+.globl get_sp_limit
+.globl get_sp
+
+record_sp_limit:
+	mov r3, r0
+	ldr r0, =my_cpu
+	mov r1, #0
+	mov r2, #0
+    stmfd   sp!, {r3, r7}
+    ldr     r7, =345
+    swi     #0
+    ldmfd   sp!, {r3, r7}
+    movs    r0, r0
+	movmi	r0, #0
+
+	ldr r1, =my_array
+	str r3, [r1, r0]
+	mov pc, lr
+
+
+get_sp_limit:
+    ldr r0, =my_cpu
+	mov r1, #0
+	mov r2, #0
+    stmfd   sp!, {r4, r7}
+    ldr     r7, =345
+    swi     #0
+    ldmfd   sp!, {r4, r7}
+    movs    r0, r0
+	movmi	r0, #0
+	mov r3, r0
+
+	ldr r1, =my_array
+	ldr r0, [r1, r3]
+	mov pc, lr
+
+
+get_sp:
+	mov r0, sp
+	mov pc, lr
+	
+.data
+my_cpu:	.long	0
+.global my_array
+my_array:	
+	.long	0
+	.long	0
+	.long	0
+	.long	0
+	.long	0
+	.long	0
+	.long	0
+	.long	0	
+.end
diff --git a/src/rt/arch/arm/regs.h b/src/rt/arch/arm/regs.h
new file mode 100644
index 00000000000..a49fcab1184
--- /dev/null
+++ b/src/rt/arch/arm/regs.h
@@ -0,0 +1,21 @@
+#define RUSTRT_RBX   0
+#define RUSTRT_RSP   1
+#define RUSTRT_RBP   2
+// RCX on Windows, RDI elsewhere
+#define RUSTRT_ARG0  3
+#define RUSTRT_R12   4
+#define RUSTRT_R13   5
+#define RUSTRT_R14   6
+#define RUSTRT_R15   7
+#define RUSTRT_IP    8
+
+#define RUSTRT_MAX  32
+
+// ARG0 is the register in which the first argument goes.
+// Naturally this depends on your operating system.
+#   define RUSTRT_ARG0_S r0
+#   define RUSTRT_ARG1_S r1
+#   define RUSTRT_ARG2_S r2
+#   define RUSTRT_ARG3_S r3
+
+