| Index: tests/common/register_set.h
|
| diff --git a/tests/common/register_set.h b/tests/common/register_set.h
|
| index 349f57a22e7ae25a71f82c2de06de9fe255ed122..1e8f10192be095035b05b2c24399f9ccfc979ded 100644
|
| --- a/tests/common/register_set.h
|
| +++ b/tests/common/register_set.h
|
| @@ -8,6 +8,7 @@
|
| #define NATIVE_CLIENT_TESTS_COMMON_REGISTER_SET_H_
|
|
|
| #include "native_client/src/include/nacl_macros.h"
|
| +#include "native_client/src/trusted/service_runtime/nacl_config.h"
|
| #include "native_client/src/trusted/service_runtime/nacl_signal.h"
|
| #include "native_client/src/trusted/service_runtime/include/sys/nacl_exception.h"
|
|
|
| @@ -104,6 +105,51 @@
|
| asm_code \
|
| : : "r"(regs) : "memory")
|
|
|
| +#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
|
| +
|
| +# define REGS_MASK_A0 "and $a0, $a0, $t7\n"
|
| +# define ASM_WITH_REGS(regs, asm_code) \
|
| + __asm__( \
|
| + ".p2align 4\n" \
|
| + "move $a0, %0\n" \
|
| + "nop\n" \
|
| + /* We skip setting zero register because it's unsettable. */ \
|
| + REGS_MASK_A0 "lw $at, 4($a0)\n" \
|
| + REGS_MASK_A0 "lw $v0, 8($a0)\n" \
|
| + REGS_MASK_A0 "lw $v1, 12($a0)\n" \
|
| + REGS_MASK_A0 "lw $a1, 20($a0)\n" \
|
| + REGS_MASK_A0 "lw $a2, 24($a0)\n" \
|
| + REGS_MASK_A0 "lw $a3, 28($a0)\n" \
|
| + REGS_MASK_A0 "lw $t0, 32($a0)\n" \
|
| + REGS_MASK_A0 "lw $t1, 36($a0)\n" \
|
| + REGS_MASK_A0 "lw $t2, 40($a0)\n" \
|
| + REGS_MASK_A0 "lw $t3, 44($a0)\n" \
|
| + REGS_MASK_A0 "lw $t4, 48($a0)\n" \
|
| + REGS_MASK_A0 "lw $t5, 52($a0)\n" \
|
| + /* We skip setting t6 and t7 because those are mask registers. */ \
|
| + REGS_MASK_A0 "lw $s0, 64($a0)\n" \
|
| + REGS_MASK_A0 "lw $s1, 68($a0)\n" \
|
| + REGS_MASK_A0 "lw $s2, 72($a0)\n" \
|
| + REGS_MASK_A0 "lw $s3, 76($a0)\n" \
|
| + REGS_MASK_A0 "lw $s4, 80($a0)\n" \
|
| + REGS_MASK_A0 "lw $s5, 84($a0)\n" \
|
| + REGS_MASK_A0 "lw $s6, 88($a0)\n" \
|
| + REGS_MASK_A0 "lw $s7, 92($a0)\n" \
|
| + /* We skip setting t8 because that register hold TLS index. */ \
|
| + REGS_MASK_A0 "lw $t9, 100($a0)\n" \
|
| + /* We skip setting k0 and k1 registers, they are changed by kernel. */ \
|
| + REGS_MASK_A0 "lw $gp, 112($a0)\n" \
|
| + REGS_MASK_A0 "lw $sp, 116($a0)\n" \
|
| + /* Value change of sp requires masking instruction. */ \
|
| + "and $sp, $sp, $t7\n" \
|
| + "nop\n" \
|
| + REGS_MASK_A0 "lw $fp, 120($a0)\n" \
|
| + REGS_MASK_A0 "lw $ra, 124($a0)\n" \
|
| + REGS_MASK_A0 "lw $a0, 16($a0)\n" \
|
| + ".p2align 4\n" /* Align for whatever comes after. */ \
|
| + asm_code \
|
| + : : "r"(regs) : "memory")
|
| +
|
| #else
|
| # error Unsupported architecture
|
| #endif
|
| @@ -117,6 +163,10 @@
|
| # define JUMP_WITH_REGS(regs, dest) ASM_WITH_REGS(regs, "jmp " #dest)
|
| #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
|
| # define JUMP_WITH_REGS(regs, dest) ASM_WITH_REGS(regs, "b " #dest)
|
| +#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
|
| +# define JUMP_WITH_REGS(regs, dest) ASM_WITH_REGS(regs, \
|
| + "b " #dest "\n" \
|
| + "nop\n")
|
| #else
|
| # error Unsupported architecture
|
| #endif
|
| @@ -294,6 +344,67 @@ extern const uint8_t kX86FlagBits[5];
|
| "b " #callee_func "\n" \
|
| ".popsection\n")
|
|
|
| +#elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
|
| +
|
| +# define REGS_SAVER_FUNC_NOPROTO(def_func, callee_func) \
|
| + void callee_func(struct NaClSignalContext *regs); \
|
| + __asm__( \
|
| + ".pushsection .text, \"ax\", %progbits\n" \
|
| + ".p2align 4\n" \
|
| + #def_func ":\n" \
|
| + /* Make space on stack for all registers. */ \
|
| + "add $sp, $sp, -132\n" \
|
| + "and $sp, $sp, $t7\n"\
|
| + "sw $zero, 0($sp)\n" \
|
| + "sw $at, 4($sp)\n" \
|
| + "sw $v0, 8($sp)\n" \
|
| + "sw $v1, 12($sp)\n" \
|
| + "sw $a0, 16($sp)\n" \
|
| + "sw $a1, 20($sp)\n" \
|
| + "sw $a2, 24($sp)\n" \
|
| + "sw $a3, 28($sp)\n" \
|
| + "sw $t0, 32($sp)\n" \
|
| + "sw $t1, 36($sp)\n" \
|
| + "sw $t2, 40($sp)\n" \
|
| + "sw $t3, 44($sp)\n" \
|
| + "sw $t4, 48($sp)\n" \
|
| + "sw $t5, 52($sp)\n" \
|
| + "sw $t6, 56($sp)\n" \
|
| + "sw $t7, 60($sp)\n" \
|
| + "sw $s0, 64($sp)\n" \
|
| + "sw $s1, 68($sp)\n" \
|
| + "sw $s2, 72($sp)\n" \
|
| + "sw $s3, 76($sp)\n" \
|
| + "sw $s4, 80($sp)\n" \
|
| + "sw $s5, 84($sp)\n" \
|
| + "sw $s6, 88($sp)\n" \
|
| + "sw $s7, 92($sp)\n" \
|
| + "sw $t8, 96($sp)\n" \
|
| + "sw $t9, 100($sp)\n" \
|
| + /* We skip saving k0 and k1 registers, they are changed by kernel. */ \
|
| + "sw $gp, 112($sp)\n" \
|
| + /* Store the value stack_ptr had on entry of this function. */ \
|
| + "add $t1, $sp, 132\n" \
|
| + "sw $t1, 116($sp)\n" \
|
| + "sw $fp, 120($sp)\n" \
|
| + "sw $ra, 124($sp)\n" \
|
| + /* Save a correct prog_ctr value. */ \
|
| + "lui $t1, %hi(" #def_func ")\n" \
|
| + "addiu $t1, $t1, %lo(" #def_func ")\n" \
|
| + "sw $t1, 128($sp)\n" \
|
| + /* Prepare argument for callee_func. */ \
|
| + "move $a0, $sp\n" \
|
| + /* Align the stack pointer. */ \
|
| + "sll $t1, $t7, 3\n" \
|
| + "and $sp, $sp, $t1\n" \
|
| + "and $sp, $sp, $t7\n" \
|
| + /* Make space on stack for convention calling registers. */ \
|
| + "add $sp, $sp, -16\n" \
|
| + "and $sp, $sp, $t7\n" \
|
| + "b " #callee_func "\n" \
|
| + "nop \n" \
|
| + ".popsection\n")
|
| +
|
| #else
|
| # error Unsupported architecture
|
| #endif
|
|
|