← Back to team overview

kicad-developers team mailing list archive

[PATCH] Add MIPS N64 support for libcontext

 

Hi

I just implemented libcontext for MIPS N64 ABI, it have already accepted by boost::context, and I ported it to KiCAD.

It have passed the test by John Beard in [RFC/PATCH] Generic utility tool, KiCAD is now running smoothly on a Loongson-3A2000 PC.

Btw: Is it possible to backport this change to 5.1.0 milestone?

Thanks

Jiaxun Yang


From 4eb02ace1f27dd6d2839f8bd776ec786297fe25e Mon Sep 17 00:00:00 2001
From: Jiaxun Yang <jiaxun.yang@xxxxxxxxxxx>
Date: Wed, 26 Dec 2018 09:28:09 +0800
Subject: [PATCH] Add MIPS N64 support for libcontext

---
 common/system/libcontext.cpp | 117 +++++++++++++++++++++++++++++++++++
 include/system/libcontext.h  |   3 +
 2 files changed, 120 insertions(+)

diff --git a/common/system/libcontext.cpp b/common/system/libcontext.cpp
index 1f1285370..434df15e6 100644
--- a/common/system/libcontext.cpp
+++ b/common/system/libcontext.cpp
@@ -710,3 +710,120 @@ __asm (
 );

 #endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_mips_n64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl jump_fcontext\n"
+".align 2\n"
+".set noreorder\n"
+".type jump_fcontext,@function\n"
+".ent jump_fcontext\n"
+"jump_fcontext:\n"
+"    # reserve space on stack\n"
+"    daddiu $sp, $sp, -176\n"
+"    sd  $s0, 64($sp)  # save S0\n"
+"    sd  $s1, 72($sp)  # save S1\n"
+"    sd  $s2, 80($sp)  # save S2\n"
+"    sd  $s3, 88($sp)  # save S3\n"
+"    sd  $s4, 96($sp)  # save S4\n"
+"    sd  $s5, 104($sp) # save S5\n"
+"    sd  $s6, 112($sp) # save S6\n"
+"    sd  $s7, 120($sp) # save S7\n"
+"    sd  $fp, 128($sp) # save FP\n"
+"    sd  $ra, 144($sp) # save RA\n"
+"    sd  $ra, 152($sp) # save RA as PC\n"
+"    s.d  $f24, 0($sp)   # save F24\n"
+"    s.d  $f25, 8($sp)   # save F25\n"
+"    s.d  $f26, 16($sp)  # save F26\n"
+"    s.d  $f27, 24($sp)  # save F27\n"
+"    s.d  $f28, 32($sp)  # save F28\n"
+"    s.d  $f29, 40($sp)  # save F29\n"
+"    s.d  $f30, 48($sp)  # save F30\n"
+"    s.d  $f31, 56($sp)  # save F31\n"
+"    # store SP (pointing to old context-data) in pointer a0(first arg)\n"
+"    sd  $sp, 0($a0)\n"
+"    # get SP (pointing to new context-data) from a1 param\n"
+"    move  $sp, $a1\n"
+"    l.d  $f24, 0($sp)   # restore F24\n"
+"    l.d  $f25, 8($sp)   # restore F25\n"
+"    l.d  $f26, 16($sp)  # restore F26\n"
+"    l.d  $f27, 24($sp)  # restore F27\n"
+"    l.d  $f28, 32($sp)  # restore F28\n"
+"    l.d  $f29, 40($sp)  # restore F29\n"
+"    l.d  $f30, 48($sp)  # restore F30\n"
+"    l.d  $f31, 56($sp)  # restore F31\n"
+"    ld  $s0, 64($sp)  # restore S0\n"
+"    ld  $s1, 72($sp)  # restore S1\n"
+"    ld  $s2, 80($sp)  # restore S2\n"
+"    ld  $s3, 88($sp)  # restore S3\n"
+"    ld  $s4, 96($sp)  # restore S4\n"
+"    ld  $s5, 104($sp) # restore S5\n"
+"    ld  $s6, 112($sp) # restore S6\n"
+"    ld  $s7, 120($sp) # restore S7\n"
+"    ld  $fp, 128($sp) # restore FP\n"
+"    ld  $ra, 144($sp) # restore RA\n"
+"    # load PC\n"
+"    ld  $t9, 152($sp)\n"
+"    sd  $a2, 160($sp)\n"
+"    # adjust stack\n"
+"    daddiu $sp, $sp, 176\n"
+"    move  $a0, $a2 # move *data from a2 to a0 as param\n"
+"    move  $v0, $a2 # move *data from a2 to v0 as return\n"
+"    # jump to context\n"
+"    jr  $t9\n"
+"    nop\n"
+".end jump_fcontext\n"
+".size jump_fcontext, .-jump_fcontext\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
+
+#if defined(LIBCONTEXT_PLATFORM_linux_mips_n64) && defined(LIBCONTEXT_COMPILER_gcc)
+__asm (
+".text\n"
+".globl make_fcontext\n"
+".align 2\n"
+".set noreorder\n"
+".type make_fcontext,@function\n"
+".ent make_fcontext\n"
+"make_fcontext:\n"
+"#ifdef __PIC__\n"
+".set    noreorder\n"
+".cpload $t9\n"
+".set    reorder\n"
+"#endif\n"
+"    # shift address in A0 to lower 16 byte boundary\n"
+"    li $v1, 0xfffffffffffffff0\n"
+"    and $v0, $v1, $a0\n"
+"    # reserve space for context-data on context-stack\n"
+"    daddiu $v0, $v0, -176\n"
+"    # third arg of make_fcontext() == address of context-function\n"
+"    sd  $a2, 152($v0)\n"
+"    # save global pointer in context-data\n"
+"    sd  $gp, 136($v0)\n"
+"    # psudo instruction compute abs address of label finish based on GP\n"
+"    dla  $t9, finish\n"
+"    # save address of finish as return-address for context-function\n"
+"    # will be entered after context-function returns\n"
+"    sd  $t9, 144($v0)\n"
+"    jr  $ra # return pointer to context-data\n"
+"    nop\n"
+"finish:\n"
+"    # reload our gp register (needed for la)\n"
+"    daddiu $t0, $sp, -176\n"
+"    ld $gp, 136($t0)\n"
+"    ld $v0, 160($t0)\n"
+"    # call _exit(0)\n"
+"    dla $t9, _exit\n"
+"    move $a0, $zero\n"
+"    jr $t9\n"
+"    nop\n"
+".end make_fcontext\n"
+".size make_fcontext, .-make_fcontext\n"
+".section .note.GNU-stack,\"\",%progbits\n"
+);
+
+#endif
+
diff --git a/include/system/libcontext.h b/include/system/libcontext.h
index e274e4315..3226353f5 100644
--- a/include/system/libcontext.h
+++ b/include/system/libcontext.h
@@ -39,6 +39,9 @@
     #elif __aarch64__
         #define LIBCONTEXT_PLATFORM_linux_arm64
         #define LIBCONTEXT_CALL_CONVENTION
+    #elif (__mips__ && _MIPS_SIM == _ABI64)
+        #define LIBCONTEXT_PLATFORM_linux_mips_n64
+        #define LIBCONTEXT_CALL_CONVENTION
     #endif

     #elif defined(__MINGW32__) || defined(__MINGW64__)
--
2.19.2



Follow ups