rt: MIPS32 support

This commit is contained in:
Jyun-Yan You 2013-01-29 13:04:51 +08:00 committed by Brian Anderson
parent d30a4f4e67
commit 0ecd9e03ff
16 changed files with 1166 additions and 5 deletions

View file

@ -0,0 +1,81 @@
.text
.globl swap_registers
.align 2
.set nomips16
.ent swap_registers
swap_registers:
.set noreorder
.set nomacro
.set noat
sw $1, 1 * 4($4)
sw $2, 2 * 4($4)
sw $3, 3 * 4($4)
sw $4, 4 * 4($4)
sw $5, 5 * 4($4)
sw $6, 6 * 4($4)
sw $7, 7 * 4($4)
sw $8, 8 * 4($4)
sw $9, 9 * 4($4)
sw $10, 10 * 4($4)
sw $11, 11 * 4($4)
sw $12, 12 * 4($4)
sw $13, 13 * 4($4)
sw $14, 14 * 4($4)
sw $15, 15 * 4($4)
sw $16, 16 * 4($4)
sw $17, 17 * 4($4)
sw $18, 18 * 4($4)
sw $19, 19 * 4($4)
sw $20, 20 * 4($4)
sw $21, 21 * 4($4)
sw $22, 22 * 4($4)
sw $23, 23 * 4($4)
sw $24, 24 * 4($4)
sw $25, 25 * 4($4)
sw $26, 26 * 4($4)
sw $27, 27 * 4($4)
sw $28, 28 * 4($4)
sw $29, 29 * 4($4)
sw $30, 30 * 4($4)
sw $31, 31 * 4($4)
lw $1, 1 * 4($5)
lw $2, 2 * 4($5)
lw $3, 3 * 4($5)
lw $4, 4 * 4($5)
lw $5, 5 * 4($5)
lw $6, 6 * 4($5)
lw $7, 7 * 4($5)
lw $8, 8 * 4($5)
lw $9, 9 * 4($5)
lw $10, 10 * 4($5)
lw $11, 11 * 4($5)
lw $12, 12 * 4($5)
lw $13, 13 * 4($5)
lw $14, 14 * 4($5)
lw $15, 15 * 4($5)
lw $16, 16 * 4($5)
lw $17, 17 * 4($5)
lw $18, 18 * 4($5)
lw $19, 19 * 4($5)
lw $20, 20 * 4($5)
lw $21, 21 * 4($5)
lw $22, 22 * 4($5)
lw $23, 23 * 4($5)
lw $24, 24 * 4($5)
lw $25, 25 * 4($5)
lw $26, 26 * 4($5)
lw $27, 27 * 4($5)
lw $28, 28 * 4($5)
lw $29, 29 * 4($5)
lw $30, 30 * 4($5)
lw $31, 31 * 4($5)
jr $31
.end swap_registers

12
src/rt/arch/mips/ccall.S Normal file
View file

@ -0,0 +1,12 @@
.text
.globl __morestack
.hidden __morestack
.align 2
.set nomips16
.ent __morestack
__morestack:
.set noreorder
.set nomacro
.end __morestack

View file

@ -0,0 +1,46 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#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[4] = (uint32_t)arg;
regs.data[29] = (uint32_t)sp;
regs.data[31] = (uint32_t)f;
// Last base pointer on the stack should be 0
}

View file

@ -0,0 +1,51 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#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

31
src/rt/arch/mips/gpr.cpp Normal file
View file

@ -0,0 +1,31 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#include "gpr.h"
#define LOAD(n) do { \
uintptr_t tmp; \
asm(".set noat; move %0, $" #n : "=r" (tmp) :); \
this->r##n = tmp; \
} while (0)
void rust_gpr::load() {
LOAD(1); LOAD(2); LOAD(3);
LOAD(4); LOAD(5); LOAD(6); LOAD(7);
LOAD(8); LOAD(9); LOAD(10); LOAD(11);
LOAD(12); LOAD(13); LOAD(14); LOAD(15);
LOAD(16); LOAD(17); LOAD(18); LOAD(19);
LOAD(20); LOAD(21); LOAD(22); LOAD(23);
LOAD(24); LOAD(25); LOAD(26); LOAD(27);
LOAD(28); LOAD(29); LOAD(30); LOAD(31);
}

33
src/rt/arch/mips/gpr.h Normal file
View file

@ -0,0 +1,33 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#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;
uintptr_t r16, r17, r18, r19, r20, r21, r22, r23;
uintptr_t r24, r25, r26, r27, r28, r29, r30, r31;
inline uintptr_t get_fp() { return r30; }
inline uintptr_t get_ip() { return r0; }
inline void set_fp(uintptr_t new_fp) { r30 = new_fp; }
inline void set_ip(uintptr_t new_ip) { r0 = new_ip; }
void load();
};
#endif

View file

@ -0,0 +1,44 @@
.text
.globl record_sp_limit
.align 2
.set nomips16
.ent record_sp_limit
record_sp_limit:
.set noreorder
.set nomacro
.set push
.set mips32r2
rdhwr $3, $29
.set pop
addiu $3, $3, -0x7008
sw $4, 4($3)
jr $31
.end record_sp_limit
.globl get_sp_limit
.align 2
.set nomips16
.ent get_sp_limit
get_sp_limit:
.set noreorder
.set nomacro
.set push
.set mips32r2
rdhwr $3, $29
.set pop
addiu $3, $3, -0x7008
lw $2, 4($3)
jr $31
.end get_sp_limit
.globl get_sp
.align 2
.set nomips16
.ent get_sp
get_sp:
.set noreorder
.set nomacro
move $2, $29
jr $31
.end get_sp

18
src/rt/arch/mips/regs.h Normal file
View file

@ -0,0 +1,18 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#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 r4
#define RUSTRT_ARG1_S r5
#define RUSTRT_ARG2_S r6
#define RUSTRT_ARG3_S r7

View file

@ -139,6 +139,9 @@
#ifdef __x86_64__
#define RED_ZONE_SIZE RZ_LINUX_64
#endif
#ifdef __mips__
#define RED_ZONE_SIZE RZ_LINUX_32
#endif
#endif
#ifdef __APPLE__
#ifdef __i386__