Skip to content
Snippets Groups Projects
Commit a85755aa authored by Damien George's avatar Damien George
Browse files

py/nlrxtensa: Convert from assembler to C file with inline asm.

nlr_jump is a little bit inefficient because it now saves a register to
the stack.
parent be3d7f91
Branches
No related tags found
No related merge requests found
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2014 Damien P. George * Copyright (c) 2014-2017 Damien P. George
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
...@@ -24,96 +24,80 @@ ...@@ -24,96 +24,80 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#if defined(__xtensa__) #include "py/mpstate.h"
#include "py/nlr.h"
/* #if !MICROPY_NLR_SETJMP && defined(__xtensa__)
calling conventions:
a0 = return address #undef nlr_push
a1 = stack pointer
a2 = first arg, return value // Xtensa calling conventions:
a3-a7 = rest of args // a0 = return address
*/ // a1 = stack pointer
// a2 = first arg, return value
// a3-a7 = rest of args
// the offset of nlr_top within mp_state_ctx_t unsigned int nlr_push(nlr_buf_t *nlr) {
#define NLR_TOP_OFFSET (2 * 4)
#define NLR_TOP (mp_state_ctx + NLR_TOP_OFFSET) __asm volatile (
"s32i.n a0, a2, 8 \n" // save regs...
"s32i.n a1, a2, 12 \n"
"s32i.n a8, a2, 16 \n"
"s32i.n a9, a2, 20 \n"
"s32i.n a10, a2, 24 \n"
"s32i.n a11, a2, 28 \n"
"s32i.n a12, a2, 32 \n"
"s32i.n a13, a2, 36 \n"
"s32i.n a14, a2, 40 \n"
"s32i.n a15, a2, 44 \n"
"j nlr_push_tail \n" // do the rest in C
);
.file "nlr.s" return 0; // needed to silence compiler warning
.text }
.literal_position __attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr) {
.literal .LC0, NLR_TOP nlr_buf_t **top = &MP_STATE_THREAD(nlr_top);
.align 4 nlr->prev = *top;
.global nlr_push *top = nlr;
.type nlr_push, @function return 0; // normal return
nlr_push: }
// save regs
s32i.n a0, a2, 8
s32i.n a1, a2, 12
s32i.n a8, a2, 16
s32i.n a9, a2, 20
s32i.n a10, a2, 24
s32i.n a11, a2, 28
s32i.n a12, a2, 32
s32i.n a13, a2, 36
s32i.n a14, a2, 40
s32i.n a15, a2, 44
l32r a3, .LC0 void nlr_pop(void) {
l32i.n a4, a3, 0 nlr_buf_t **top = &MP_STATE_THREAD(nlr_top);
s32i.n a2, a3, 0 *top = (*top)->prev;
s32i.n a4, a2, 0 }
movi.n a2, 0
ret.n
.size nlr_push, .-nlr_push
.literal_position NORETURN void nlr_jump(void *val) {
.literal .LC1, NLR_TOP nlr_buf_t **top_ptr = &MP_STATE_THREAD(nlr_top);
.align 4 nlr_buf_t *top = *top_ptr;
.global nlr_pop if (top == NULL) {
.type nlr_pop, @function nlr_jump_fail(val);
nlr_pop: }
l32r a2, .LC1
l32i.n a3, a2, 0
l32i.n a3, a3, 0
s32i.n a3, a2, 0
ret.n
.size nlr_pop, .-nlr_pop
.literal_position top->ret_val = val;
.literal .LC2, NLR_TOP *top_ptr = top->prev;
.align 4
.global nlr_jump
.type nlr_jump, @function
nlr_jump:
l32r a3, .LC2
l32i.n a3, a3, 0 // a3 = nlr_top
bnez.n a3, .L4
call0 nlr_jump_fail
.L4:
s32i.n a2, a3, 4 // nlr_top->ret_val = val
// restore regs __asm volatile (
l32i.n a0, a3, 8 "mov.n a2, %0 \n" // a2 points to nlr_buf
l32i.n a1, a3, 12 "l32i.n a0, a2, 8 \n" // restore regs...
l32i.n a8, a3, 16 "l32i.n a1, a2, 12 \n"
l32i.n a9, a3, 20 "l32i.n a8, a2, 16 \n"
l32i.n a10, a3, 24 "l32i.n a9, a2, 20 \n"
l32i.n a11, a3, 28 "l32i.n a10, a2, 24 \n"
l32i.n a12, a3, 32 "l32i.n a11, a2, 28 \n"
l32i.n a13, a3, 36 "l32i.n a12, a2, 32 \n"
l32i.n a14, a3, 40 "l32i.n a13, a2, 36 \n"
l32i.n a15, a3, 44 "l32i.n a14, a2, 40 \n"
"l32i.n a15, a2, 44 \n"
"movi.n a2, 1 \n" // return 1, non-local return
"ret.n \n" // return
: // output operands
: "r"(top) // input operands
: // clobbered registers
);
l32i.n a3, a3, 0 // a3 = nlr_top->prev for (;;); // needed to silence compiler warning
l32r a2, .LC2 }
s32i.n a3, a2, 0 // nlr_top = a3
movi.n a2, 1 // return 1
ret.n
.size nlr_jump, .-nlr_jump
#endif // defined(__xtensa__) #endif // !MICROPY_NLR_SETJMP && defined(__xtensa__)
#if defined(linux)
.section .note.GNU-stack,"",%progbits
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment