about summary refs log tree commit diff
path: root/src/rt
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
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')
-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
-rw-r--r--src/rt/rust_android_dummy.cpp61
-rw-r--r--src/rt/rust_android_dummy.h5
-rw-r--r--src/rt/rust_builtin.cpp21
-rw-r--r--src/rt/rust_sched_loop.cpp1
-rw-r--r--src/rt/rust_task.h3
13 files changed, 364 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
+
+
diff --git a/src/rt/rust_android_dummy.cpp b/src/rt/rust_android_dummy.cpp
new file mode 100644
index 00000000000..76aa51723ef
--- /dev/null
+++ b/src/rt/rust_android_dummy.cpp
@@ -0,0 +1,61 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "rust_android_dummy.h"
+#include <math.h>
+
+#ifdef __ANDROID__
+
+int backtrace(void **array, int size) { return 0; }
+
+char **backtrace_symbols(void *const *array, int size) { return 0; }
+
+void backtrace_symbols_fd (void *const *array, int size, int fd) {}
+
+
+extern "C" float log2f(float f)
+{
+    return logf( f ) / logf( 2 );
+}
+
+extern "C" double log2( double n )
+{
+    return log( n ) / log( 2 );
+}
+
+extern "C" void telldir()
+{
+}
+
+extern "C" void seekdir()
+{
+}
+
+extern "C" void mkfifo()
+{
+}
+
+extern "C" void abs()
+{
+}
+
+extern "C" void labs()
+{
+}
+
+extern "C" void rand()
+{
+}
+
+extern "C" void srand()
+{
+}
+
+extern "C" void atof()
+{
+}
+extern "C" void tgammaf()
+{
+}
+#endif
diff --git a/src/rt/rust_android_dummy.h b/src/rt/rust_android_dummy.h
new file mode 100644
index 00000000000..2e8b6f2c766
--- /dev/null
+++ b/src/rt/rust_android_dummy.h
@@ -0,0 +1,5 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "execinfo.h"
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index b16006e1f91..0919ccf7f0e 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -33,6 +33,27 @@
 extern char **environ;
 #endif
 
+#ifdef __ANDROID__
+time_t
+timegm(struct tm *tm)
+{
+    time_t ret;
+    char *tz;
+
+    tz = getenv("TZ");
+    setenv("TZ", "", 1);
+    tzset();
+    ret = mktime(tm);
+    if (tz)
+        setenv("TZ", tz, 1);
+    else
+        unsetenv("TZ");
+    tzset();
+    return ret;
+}
+#endif
+
+
 extern "C" CDECL rust_str*
 last_os_error() {
     rust_task *task = rust_get_current_task();
diff --git a/src/rt/rust_sched_loop.cpp b/src/rt/rust_sched_loop.cpp
index e56ce6dd263..5ddfd88d4b4 100644
--- a/src/rt/rust_sched_loop.cpp
+++ b/src/rt/rust_sched_loop.cpp
@@ -28,6 +28,7 @@ rust_sched_loop::rust_sched_loop(rust_scheduler *sched, int id, bool killed) :
     id(id),
     should_exit(false),
     cached_c_stack(NULL),
+    extra_c_stack(NULL),
     dead_task(NULL),
     killed(killed),
     pump_signal(NULL),
diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h
index 27694becdfb..20c9a48f1dd 100644
--- a/src/rt/rust_task.h
+++ b/src/rt/rust_task.h
@@ -165,6 +165,9 @@
 #define RED_ZONE_SIZE RZ_BSD_64
 #endif
 #endif
+#ifdef __ANDROID__
+#define RED_ZONE_SIZE RZ_MAC_32
+#endif
 
 struct rust_box;