diff options
| author | kyeongwoon <kyeongwoon.lee@samsung.com> | 2012-11-30 09:21:49 +0900 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-01-13 16:43:39 -0800 |
| commit | 987f824f233faee4aed39dac92a1b442d42965cc (patch) | |
| tree | 2cf1b078738e9bf580b9ee43f674d95c403751fa /src/rt | |
| parent | 27e6a0fa5651dbda55773488c8b706adfa5cefc2 (diff) | |
| download | rust-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.S | 47 | ||||
| -rw-r--r-- | src/rt/arch/arm/ccall.S | 27 | ||||
| -rw-r--r-- | src/rt/arch/arm/context.cpp | 36 | ||||
| -rw-r--r-- | src/rt/arch/arm/context.h | 43 | ||||
| -rw-r--r-- | src/rt/arch/arm/gpr.cpp | 15 | ||||
| -rw-r--r-- | src/rt/arch/arm/gpr.h | 23 | ||||
| -rw-r--r-- | src/rt/arch/arm/record_sp.S | 61 | ||||
| -rw-r--r-- | src/rt/arch/arm/regs.h | 21 | ||||
| -rw-r--r-- | src/rt/rust_android_dummy.cpp | 61 | ||||
| -rw-r--r-- | src/rt/rust_android_dummy.h | 5 | ||||
| -rw-r--r-- | src/rt/rust_builtin.cpp | 21 | ||||
| -rw-r--r-- | src/rt/rust_sched_loop.cpp | 1 | ||||
| -rw-r--r-- | src/rt/rust_task.h | 3 |
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*)®s == (void*)this); + memset(®s, 0, sizeof(regs)); +} + +void context::swap(context &out) +{ + swap_registers(&out.regs, ®s); +} + +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; |
