Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
fiber_switchContext for MIPS_O32
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinNowak committed Dec 25, 2012
1 parent 43dacb8 commit a57b29c
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 8 deletions.
64 changes: 59 additions & 5 deletions src/core/thread.d
Expand Up @@ -5,7 +5,7 @@
* License: Distributed under the
* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
* (See accompanying file LICENSE)
* Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen
* Authors: Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
* Source: $(DRUNTIMESRC core/_thread.d)
*/

Expand Down Expand Up @@ -3135,7 +3135,18 @@ private
else version( PPC )
{
version( Posix )
{
version = AsmPPC_Posix;
version = AsmExternal;
}
}
else version( MIPS_O32 )
{
version( Posix )
{
version = AsmMIPS_O32_Posix;
version = AsmExternal;
}
}


Expand All @@ -3147,7 +3158,7 @@ private
version( AsmX86_Posix ) {} else
version( AsmX86_64_Windows ) {} else
version( AsmX86_64_Posix ) {} else
version( AsmPPC_Posix ) {} else
version( AsmExternal ) {} else
{
// NOTE: The ucontext implementation requires architecture specific
// data definitions to operate so testing for it must be done
Expand Down Expand Up @@ -3223,9 +3234,7 @@ private
}


// NOTE: If AsmPPC_Posix is defined then the context switch routine will
// be defined externally until inline PPC ASM is supported.
version( AsmPPC_Posix )
version( AsmExternal )
extern (C) void fiber_switchContext( void** oldp, void* newp );
else
extern (C) void fiber_switchContext( void** oldp, void* newp )
Expand Down Expand Up @@ -3385,6 +3394,8 @@ private
swapcontext( **(cast(ucontext_t***) oldp),
*(cast(ucontext_t**) newp) );
}
else
static assert(0, "Not implemented");
}
}

Expand Down Expand Up @@ -4160,6 +4171,47 @@ private:

assert( (cast(size_t) pstack & 0x0f) == 0 );
}
else version( AsmMIPS_O32_Posix )
{
version (StackGrowsDown) {}
else static assert(0);

/* We keep the FP registers and the return address below
* the stack pointer, so they don't get scanned by the
* GC. The last frame before swapping the stack pointer is
* organized like the following.
*
* |-----------|<= frame pointer
* | $gp |
* | $s0-8 |
* |-----------|<= stack pointer
* | $ra |
* | align(8) |
* | $f20-30 |
* |-----------|
*
*/
enum SZ_GP = 10 * size_t.sizeof; // $gp + $s0-8
enum SZ_RA = size_t.sizeof; // $ra
version (MIPS_HardFloat)
{
enum SZ_FP = 6 * 8; // $f20-30
enum ALIGN = -(SZ_FP + SZ_RA) & (8 - 1);
}
else
{
enum SZ_FP = 0;
enum ALIGN = 0;
}

enum BELOW = SZ_FP + ALIGN + SZ_RA;
enum ABOVE = SZ_GP;
enum SZ = BELOW + ABOVE;

(cast(ubyte*)pstack - SZ)[0 .. SZ] = 0;
pstack -= ABOVE;
*cast(size_t*)(pstack - SZ_RA) = cast(size_t)&fiber_entryPoint;
}
else static if( __traits( compiles, ucontext_t ) )
{
getcontext( &m_utxt );
Expand All @@ -4170,6 +4222,8 @@ private:
// be a pointer to the ucontext_t struct for that fiber.
push( cast(size_t) &m_utxt );
}
else
static assert(0, "Not implemented");
}


Expand Down
78 changes: 75 additions & 3 deletions src/core/threadasm.S
@@ -1,13 +1,13 @@
/**
* Support code for mutithreading.
*
* Copyright: Copyright Mikola Lysenko 2005 - 2009.
* Copyright: Copyright Mikola Lysenko 2005 - 2012.
* License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
* Authors: Mikola Lysenko
* Authors: Mikola Lysenko, Martin Nowak
*/

/*
* Copyright Mikola Lysenko 2005 - 2009.
* Copyright Mikola Lysenko 2005 - 2012.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
Expand Down Expand Up @@ -142,4 +142,76 @@ _fiber_switchContext:
/* Return and switch context */
blr

#elif defined(__mips__) && _MIPS_SIM == _ABIO32
/************************************************************************************
* MIPS ASM BITS
************************************************************************************/

/**
* Performs a context switch.
*
* $a0 - void** - ptr to old stack pointer
* $a1 - void* - new stack pointer
*
*/
.text
.globl fiber_switchContext
fiber_switchContext:
addiu $sp, $sp, -(10 * 4)

// fp regs and return address are stored below the stack
// because we don't want the GC to scan them.

#ifdef __mips_hard_float
#define ALIGN8(val) (val + (-val & 7))
#define BELOW (ALIGN8(6 * 8 + 4))
sdcl $f20, (0 * 8 - BELOW)($sp)
sdcl $f22, (1 * 8 - BELOW)($sp)
sdcl $f24, (2 * 8 - BELOW)($sp)
sdcl $f26, (3 * 8 - BELOW)($sp)
sdcl $f28, (4 * 8 - BELOW)($sp)
sdcl $f30, (5 * 8 - BELOW)($sp)
#endif
sw $ra, -4($sp)

sw $s0, (0 * 4)($sp)
sw $s1, (1 * 4)($sp)
sw $s2, (2 * 4)($sp)
sw $s3, (3 * 4)($sp)
sw $s4, (4 * 4)($sp)
sw $s5, (5 * 4)($sp)
sw $s6, (6 * 4)($sp)
sw $s7, (7 * 4)($sp)
sw $s8, (8 * 4)($sp)
sw $gp, (9 * 4)($sp)

// swap stack pointer
sw $sp, 0($a0)
move $sp, $a1

#ifdef __mips_hard_float
ldcl $f20, (0 * 8 - BELOW)($sp)
ldcl $f22, (1 * 8 - BELOW)($sp)
ldcl $f24, (2 * 8 - BELOW)($sp)
ldcl $f26, (3 * 8 - BELOW)($sp)
ldcl $f28, (4 * 8 - BELOW)($sp)
ldcl $f30, (5 * 8 - BELOW)($sp)
#endif
lw $ra, -4($sp)

lw $s0, (0 * 4)($sp)
lw $s1, (1 * 4)($sp)
lw $s2, (2 * 4)($sp)
lw $s3, (3 * 4)($sp)
lw $s4, (4 * 4)($sp)
lw $s5, (5 * 4)($sp)
lw $s6, (6 * 4)($sp)
lw $s7, (7 * 4)($sp)
lw $s8, (8 * 4)($sp)
lw $gp, (9 * 4)($sp)

addiu $sp, $sp, (10 * 4)

jr $ra // return

#endif

0 comments on commit a57b29c

Please sign in to comment.