Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
d509ac25
Commit
d509ac25
authored
May 07, 2014
by
Damien George
Browse files
py: Fix stack access in thumb native emitter.
parent
be6aa53c
Changes
6
Hide whitespace changes
Inline
Side-by-side
py/asmthumb.c
View file @
d509ac25
...
...
@@ -166,15 +166,29 @@ STATIC void asm_thumb_write_word32(asm_thumb_t *as, int w32) {
#define OP_ADD_SP(num_words) (0xb000 | (num_words))
#define OP_SUB_SP(num_words) (0xb080 | (num_words))
// locals:
// - stored on the stack in ascending order
// - numbered 0 through as->num_locals-1
// - SP points to first local
//
// | SP
// v
// l0 l1 l2 ... l(n-1)
// ^ ^
// | low address | high address in RAM
void
asm_thumb_entry
(
asm_thumb_t
*
as
,
int
num_locals
)
{
// work out what to push and how many extra space to reserve on stack
// work out what to push and how many extra space
s
to reserve on stack
// so that we have enough for all locals and it's aligned an 8-byte boundary
// we push extra regs (r1, r2, r3) to help do the stack adjustment
// we probably should just always subtract from sp, since this would be more efficient
// for push rlist, lowest numbered register at the lowest address
uint
reglist
;
uint
stack_adjust
;
if
(
num_locals
<
0
)
{
num_locals
=
0
;
}
// don't
p
pop r0 because it's used for return value
// don't pop r0 because it's used for return value
switch
(
num_locals
)
{
case
0
:
reglist
=
0xf2
;
...
...
@@ -398,14 +412,14 @@ void asm_thumb_mov_reg_i32_aligned(asm_thumb_t *as, uint reg_dest, int i32) {
void
asm_thumb_mov_local_reg
(
asm_thumb_t
*
as
,
int
local_num
,
uint
rlo_src
)
{
assert
(
rlo_src
<
REG_R8
);
int
word_offset
=
as
->
num_locals
-
local_num
-
1
;
int
word_offset
=
local_num
;
assert
(
as
->
pass
<
ASM_THUMB_PASS_EMIT
||
word_offset
>=
0
);
asm_thumb_op16
(
as
,
OP_STR_TO_SP_OFFSET
(
rlo_src
,
word_offset
));
}
void
asm_thumb_mov_reg_local
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
int
local_num
)
{
assert
(
rlo_dest
<
REG_R8
);
int
word_offset
=
as
->
num_locals
-
local_num
-
1
;
int
word_offset
=
local_num
;
assert
(
as
->
pass
<
ASM_THUMB_PASS_EMIT
||
word_offset
>=
0
);
asm_thumb_op16
(
as
,
OP_LDR_FROM_SP_OFFSET
(
rlo_dest
,
word_offset
));
}
...
...
@@ -414,7 +428,7 @@ void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) {
void
asm_thumb_mov_reg_local_addr
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
int
local_num
)
{
assert
(
rlo_dest
<
REG_R8
);
int
word_offset
=
as
->
num_locals
-
local_num
-
1
;
int
word_offset
=
local_num
;
assert
(
as
->
pass
<
ASM_THUMB_PASS_EMIT
||
word_offset
>=
0
);
asm_thumb_op16
(
as
,
OP_ADD_REG_SP_OFFSET
(
rlo_dest
,
word_offset
));
}
...
...
py/emitnative.c
View file @
d509ac25
...
...
@@ -260,9 +260,9 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
if
(
i
==
0
)
{
asm_x64_mov_r64_to_r64
(
emit
->
as
,
REG_ARG_1
,
REG_LOCAL_1
);
}
else
if
(
i
==
1
)
{
asm_x64_mov_r64_to_local
(
emit
->
as
,
REG_ARG_2
,
i
-
1
);
asm_x64_mov_r64_to_local
(
emit
->
as
,
REG_ARG_2
,
i
-
REG_LOCAL_NUM
);
}
else
if
(
i
==
2
)
{
asm_x64_mov_r64_to_local
(
emit
->
as
,
REG_ARG_3
,
i
-
1
);
asm_x64_mov_r64_to_local
(
emit
->
as
,
REG_ARG_3
,
i
-
REG_LOCAL_NUM
);
}
else
{
// TODO not implemented
assert
(
0
);
...
...
@@ -739,7 +739,7 @@ STATIC void emit_native_load_fast(emit_t *emit, qstr qstr, uint id_flags, int lo
emit_post_push_reg
(
emit
,
vtype
,
REG_LOCAL_1
);
}
else
{
need_reg_single
(
emit
,
REG_RAX
,
0
);
asm_x64_mov_local_to_r64
(
emit
->
as
,
local_num
-
1
,
REG_RAX
);
asm_x64_mov_local_to_r64
(
emit
->
as
,
local_num
-
REG_LOCAL_NUM
,
REG_RAX
);
emit_post_push_reg
(
emit
,
vtype
,
REG_RAX
);
}
#elif N_THUMB
...
...
@@ -751,7 +751,7 @@ STATIC void emit_native_load_fast(emit_t *emit, qstr qstr, uint id_flags, int lo
emit_post_push_reg
(
emit
,
vtype
,
REG_LOCAL_3
);
}
else
{
need_reg_single
(
emit
,
REG_R0
,
0
);
asm_thumb_mov_reg_local
(
emit
->
as
,
REG_R0
,
local_num
-
1
);
asm_thumb_mov_reg_local
(
emit
->
as
,
REG_R0
,
local_num
-
REG_LOCAL_NUM
);
emit_post_push_reg
(
emit
,
vtype
,
REG_R0
);
}
#endif
...
...
@@ -820,7 +820,7 @@ STATIC void emit_native_store_fast(emit_t *emit, qstr qstr, int local_num) {
emit_pre_pop_reg
(
emit
,
&
vtype
,
REG_LOCAL_1
);
}
else
{
emit_pre_pop_reg
(
emit
,
&
vtype
,
REG_RAX
);
asm_x64_mov_r64_to_local
(
emit
->
as
,
REG_RAX
,
local_num
-
1
);
asm_x64_mov_r64_to_local
(
emit
->
as
,
REG_RAX
,
local_num
-
REG_LOCAL_NUM
);
}
#elif N_THUMB
if
(
local_num
==
0
)
{
...
...
@@ -831,7 +831,7 @@ STATIC void emit_native_store_fast(emit_t *emit, qstr qstr, int local_num) {
emit_pre_pop_reg
(
emit
,
&
vtype
,
REG_LOCAL_3
);
}
else
{
emit_pre_pop_reg
(
emit
,
&
vtype
,
REG_R0
);
asm_thumb_mov_local_reg
(
emit
->
as
,
local_num
-
1
,
REG_R0
);
asm_thumb_mov_local_reg
(
emit
->
as
,
local_num
-
REG_LOCAL_NUM
,
REG_R0
);
}
#endif
...
...
tests/pybnative/for.py
0 → 100644
View file @
d509ac25
import
pyb
@
micropython
.
native
def
f1
(
n
):
for
i
in
range
(
n
):
print
(
i
)
f1
(
4
)
@
micropython
.
native
def
f2
(
r
):
for
i
in
r
:
print
(
i
)
f2
(
range
(
4
))
tests/pybnative/for.py.exp
0 → 100644
View file @
d509ac25
0
1
2
3
0
1
2
3
tests/pybnative/while.py
View file @
d509ac25
import
pyb
@
micropython
.
native
def
f
(
led
,
n
):
def
f
(
led
,
n
,
d
):
led
.
off
()
i
=
0
while
i
<
n
:
print
(
i
)
led
.
toggle
()
d
=
pyb
.
delay
d
(
50
)
# pyb.delay(50) doesn't work!
pyb
.
delay
(
d
)
i
+=
1
print
(
i
)
led
.
off
()
f
(
pyb
.
LED
(
1
),
2
)
f
(
pyb
.
LED
(
2
),
4
)
f
(
pyb
.
LED
(
1
),
2
,
150
)
f
(
pyb
.
LED
(
2
),
4
,
50
)
tests/pybnative/while.py.exp
View file @
d509ac25
0
1
2
0
1
2
3
4
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment