Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
uPython-mirror
Commits
36db6bcf
Commit
36db6bcf
authored
May 07, 2014
by
Damien George
Browse files
py, compiler: Improve passes; add an extra pass for native emitter.
parent
ca25c15d
Changes
12
Hide whitespace changes
Inline
Side-by-side
py/asmthumb.c
View file @
36db6bcf
...
@@ -42,7 +42,7 @@
...
@@ -42,7 +42,7 @@
#define SIGNED_FIT12(x) (((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800)
#define SIGNED_FIT12(x) (((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800)
struct
_asm_thumb_t
{
struct
_asm_thumb_t
{
int
pass
;
u
int
pass
;
uint
code_offset
;
uint
code_offset
;
uint
code_size
;
uint
code_size
;
byte
*
code_base
;
byte
*
code_base
;
...
@@ -58,14 +58,9 @@ struct _asm_thumb_t {
...
@@ -58,14 +58,9 @@ struct _asm_thumb_t {
asm_thumb_t
*
asm_thumb_new
(
uint
max_num_labels
)
{
asm_thumb_t
*
asm_thumb_new
(
uint
max_num_labels
)
{
asm_thumb_t
*
as
;
asm_thumb_t
*
as
;
as
=
m_new
(
asm_thumb_t
,
1
);
as
=
m_new0
(
asm_thumb_t
,
1
);
as
->
pass
=
0
;
as
->
code_offset
=
0
;
as
->
code_size
=
0
;
as
->
code_base
=
NULL
;
as
->
max_num_labels
=
max_num_labels
;
as
->
max_num_labels
=
max_num_labels
;
as
->
label_offsets
=
m_new
(
int
,
max_num_labels
);
as
->
label_offsets
=
m_new
(
int
,
max_num_labels
);
as
->
num_locals
=
0
;
return
as
;
return
as
;
}
}
...
@@ -89,16 +84,16 @@ void asm_thumb_free(asm_thumb_t *as, bool free_code) {
...
@@ -89,16 +84,16 @@ void asm_thumb_free(asm_thumb_t *as, bool free_code) {
m_del_obj
(
asm_thumb_t
,
as
);
m_del_obj
(
asm_thumb_t
,
as
);
}
}
void
asm_thumb_start_pass
(
asm_thumb_t
*
as
,
int
pass
)
{
void
asm_thumb_start_pass
(
asm_thumb_t
*
as
,
u
int
pass
)
{
as
->
pass
=
pass
;
as
->
pass
=
pass
;
as
->
code_offset
=
0
;
as
->
code_offset
=
0
;
if
(
pass
==
ASM_THUMB_PASS_
2
)
{
if
(
pass
==
ASM_THUMB_PASS_
COMPUTE
)
{
memset
(
as
->
label_offsets
,
-
1
,
as
->
max_num_labels
*
sizeof
(
int
));
memset
(
as
->
label_offsets
,
-
1
,
as
->
max_num_labels
*
sizeof
(
int
));
}
}
}
}
void
asm_thumb_end_pass
(
asm_thumb_t
*
as
)
{
void
asm_thumb_end_pass
(
asm_thumb_t
*
as
)
{
if
(
as
->
pass
==
ASM_THUMB_PASS_
2
)
{
if
(
as
->
pass
==
ASM_THUMB_PASS_
COMPUTE
)
{
// calculate size of code in bytes
// calculate size of code in bytes
as
->
code_size
=
as
->
code_offset
;
as
->
code_size
=
as
->
code_offset
;
as
->
code_base
=
m_new
(
byte
,
as
->
code_size
);
as
->
code_base
=
m_new
(
byte
,
as
->
code_size
);
...
@@ -120,7 +115,7 @@ void asm_thumb_end_pass(asm_thumb_t *as) {
...
@@ -120,7 +115,7 @@ void asm_thumb_end_pass(asm_thumb_t *as) {
// all functions must go through this one to emit bytes
// all functions must go through this one to emit bytes
STATIC
byte
*
asm_thumb_get_cur_to_write_bytes
(
asm_thumb_t
*
as
,
int
num_bytes_to_write
)
{
STATIC
byte
*
asm_thumb_get_cur_to_write_bytes
(
asm_thumb_t
*
as
,
int
num_bytes_to_write
)
{
//printf("emit %d\n", num_bytes_to_write);
//printf("emit %d\n", num_bytes_to_write);
if
(
as
->
pass
<
ASM_THUMB_PASS_
3
)
{
if
(
as
->
pass
<
ASM_THUMB_PASS_
EMIT
)
{
as
->
code_offset
+=
num_bytes_to_write
;
as
->
code_offset
+=
num_bytes_to_write
;
return
as
->
dummy_data
;
return
as
->
dummy_data
;
}
else
{
}
else
{
...
@@ -224,12 +219,12 @@ void asm_thumb_exit(asm_thumb_t *as) {
...
@@ -224,12 +219,12 @@ void asm_thumb_exit(asm_thumb_t *as) {
void
asm_thumb_label_assign
(
asm_thumb_t
*
as
,
uint
label
)
{
void
asm_thumb_label_assign
(
asm_thumb_t
*
as
,
uint
label
)
{
assert
(
label
<
as
->
max_num_labels
);
assert
(
label
<
as
->
max_num_labels
);
if
(
as
->
pass
==
ASM_THUMB_PASS_
2
)
{
if
(
as
->
pass
<
ASM_THUMB_PASS_
EMIT
)
{
// assign label offset
// assign label offset
assert
(
as
->
label_offsets
[
label
]
==
-
1
);
assert
(
as
->
label_offsets
[
label
]
==
-
1
);
as
->
label_offsets
[
label
]
=
as
->
code_offset
;
as
->
label_offsets
[
label
]
=
as
->
code_offset
;
}
else
if
(
as
->
pass
==
ASM_THUMB_PASS_3
)
{
}
else
{
// ensure label offset has not changed from PASS_
2
to PASS_
3
// ensure label offset has not changed from PASS_
COMPUTE
to PASS_
EMIT
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
assert
(
as
->
label_offsets
[
label
]
==
as
->
code_offset
);
assert
(
as
->
label_offsets
[
label
]
==
as
->
code_offset
);
}
}
...
@@ -383,20 +378,35 @@ void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) {
...
@@ -383,20 +378,35 @@ void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) {
}
}
}
}
// i32 is stored as a full word in the code, and aligned to machine-word boundary
// TODO this is very inefficient, improve it!
void
asm_thumb_mov_reg_i32_aligned
(
asm_thumb_t
*
as
,
uint
reg_dest
,
int
i32
)
{
// align on machine-word + 2
if
((
as
->
code_offset
&
3
)
==
0
)
{
asm_thumb_op16
(
as
,
ASM_THUMB_OP_NOP
);
}
// jump over the i32 value (instruction prefect adds 4 to PC)
asm_thumb_op16
(
as
,
OP_B_N
(
0
));
// store i32 on machine-word aligned boundary
asm_thumb_data
(
as
,
4
,
i32
);
// do the actual load of the i32 value
asm_thumb_mov_reg_i32_optimised
(
as
,
reg_dest
,
i32
);
}
#define OP_STR_TO_SP_OFFSET(rlo_dest, word_offset) (0x9000 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
#define OP_STR_TO_SP_OFFSET(rlo_dest, word_offset) (0x9000 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
#define OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset) (0x9800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
#define OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset) (0x9800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff))
void
asm_thumb_mov_local_reg
(
asm_thumb_t
*
as
,
int
local_num
,
uint
rlo_src
)
{
void
asm_thumb_mov_local_reg
(
asm_thumb_t
*
as
,
int
local_num
,
uint
rlo_src
)
{
assert
(
rlo_src
<
REG_R8
);
assert
(
rlo_src
<
REG_R8
);
int
word_offset
=
as
->
num_locals
-
local_num
-
1
;
int
word_offset
=
as
->
num_locals
-
local_num
-
1
;
assert
(
as
->
pass
<
ASM_THUMB_PASS_
3
||
word_offset
>=
0
);
assert
(
as
->
pass
<
ASM_THUMB_PASS_
EMIT
||
word_offset
>=
0
);
asm_thumb_op16
(
as
,
OP_STR_TO_SP_OFFSET
(
rlo_src
,
word_offset
));
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
)
{
void
asm_thumb_mov_reg_local
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
int
local_num
)
{
assert
(
rlo_dest
<
REG_R8
);
assert
(
rlo_dest
<
REG_R8
);
int
word_offset
=
as
->
num_locals
-
local_num
-
1
;
int
word_offset
=
as
->
num_locals
-
local_num
-
1
;
assert
(
as
->
pass
<
ASM_THUMB_PASS_
3
||
word_offset
>=
0
);
assert
(
as
->
pass
<
ASM_THUMB_PASS_
EMIT
||
word_offset
>=
0
);
asm_thumb_op16
(
as
,
OP_LDR_FROM_SP_OFFSET
(
rlo_dest
,
word_offset
));
asm_thumb_op16
(
as
,
OP_LDR_FROM_SP_OFFSET
(
rlo_dest
,
word_offset
));
}
}
...
@@ -405,7 +415,7 @@ void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) {
...
@@ -405,7 +415,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
)
{
void
asm_thumb_mov_reg_local_addr
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
int
local_num
)
{
assert
(
rlo_dest
<
REG_R8
);
assert
(
rlo_dest
<
REG_R8
);
int
word_offset
=
as
->
num_locals
-
local_num
-
1
;
int
word_offset
=
as
->
num_locals
-
local_num
-
1
;
assert
(
as
->
pass
<
ASM_THUMB_PASS_
3
||
word_offset
>=
0
);
assert
(
as
->
pass
<
ASM_THUMB_PASS_
EMIT
||
word_offset
>=
0
);
asm_thumb_op16
(
as
,
OP_ADD_REG_SP_OFFSET
(
rlo_dest
,
word_offset
));
asm_thumb_op16
(
as
,
OP_ADD_REG_SP_OFFSET
(
rlo_dest
,
word_offset
));
}
}
...
...
py/asmthumb.h
View file @
36db6bcf
...
@@ -24,9 +24,8 @@
...
@@ -24,9 +24,8 @@
* THE SOFTWARE.
* THE SOFTWARE.
*/
*/
#define ASM_THUMB_PASS_1 (1)
#define ASM_THUMB_PASS_COMPUTE (1)
#define ASM_THUMB_PASS_2 (2)
#define ASM_THUMB_PASS_EMIT (2)
#define ASM_THUMB_PASS_3 (3)
#define REG_R0 (0)
#define REG_R0 (0)
#define REG_R1 (1)
#define REG_R1 (1)
...
@@ -71,7 +70,7 @@ typedef struct _asm_thumb_t asm_thumb_t;
...
@@ -71,7 +70,7 @@ typedef struct _asm_thumb_t asm_thumb_t;
asm_thumb_t
*
asm_thumb_new
(
uint
max_num_labels
);
asm_thumb_t
*
asm_thumb_new
(
uint
max_num_labels
);
void
asm_thumb_free
(
asm_thumb_t
*
as
,
bool
free_code
);
void
asm_thumb_free
(
asm_thumb_t
*
as
,
bool
free_code
);
void
asm_thumb_start_pass
(
asm_thumb_t
*
as
,
int
pass
);
void
asm_thumb_start_pass
(
asm_thumb_t
*
as
,
u
int
pass
);
void
asm_thumb_end_pass
(
asm_thumb_t
*
as
);
void
asm_thumb_end_pass
(
asm_thumb_t
*
as
);
uint
asm_thumb_get_code_size
(
asm_thumb_t
*
as
);
uint
asm_thumb_get_code_size
(
asm_thumb_t
*
as
);
void
*
asm_thumb_get_code
(
asm_thumb_t
*
as
);
void
*
asm_thumb_get_code
(
asm_thumb_t
*
as
);
...
@@ -188,6 +187,7 @@ void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label);
...
@@ -188,6 +187,7 @@ void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label);
void
asm_thumb_mov_reg_i32
(
asm_thumb_t
*
as
,
uint
reg_dest
,
machine_uint_t
i32_src
);
// convenience
void
asm_thumb_mov_reg_i32
(
asm_thumb_t
*
as
,
uint
reg_dest
,
machine_uint_t
i32_src
);
// convenience
void
asm_thumb_mov_reg_i32_optimised
(
asm_thumb_t
*
as
,
uint
reg_dest
,
int
i32_src
);
// convenience
void
asm_thumb_mov_reg_i32_optimised
(
asm_thumb_t
*
as
,
uint
reg_dest
,
int
i32_src
);
// convenience
void
asm_thumb_mov_reg_i32_aligned
(
asm_thumb_t
*
as
,
uint
reg_dest
,
int
i32
);
// convenience
void
asm_thumb_mov_local_reg
(
asm_thumb_t
*
as
,
int
local_num_dest
,
uint
rlo_src
);
// convenience
void
asm_thumb_mov_local_reg
(
asm_thumb_t
*
as
,
int
local_num_dest
,
uint
rlo_src
);
// convenience
void
asm_thumb_mov_reg_local
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
int
local_num
);
// convenience
void
asm_thumb_mov_reg_local
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
int
local_num
);
// convenience
void
asm_thumb_mov_reg_local_addr
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
int
local_num
);
// convenience
void
asm_thumb_mov_reg_local_addr
(
asm_thumb_t
*
as
,
uint
rlo_dest
,
int
local_num
);
// convenience
...
...
py/asmx64.c
View file @
36db6bcf
...
@@ -112,7 +112,7 @@
...
@@ -112,7 +112,7 @@
#define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)
#define SIGNED_FIT8(x) (((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)
struct
_asm_x64_t
{
struct
_asm_x64_t
{
int
pass
;
u
int
pass
;
uint
code_offset
;
uint
code_offset
;
uint
code_size
;
uint
code_size
;
byte
*
code_base
;
byte
*
code_base
;
...
@@ -138,14 +138,9 @@ void *alloc_mem(uint req_size, uint *alloc_size, bool is_exec) {
...
@@ -138,14 +138,9 @@ void *alloc_mem(uint req_size, uint *alloc_size, bool is_exec) {
asm_x64_t
*
asm_x64_new
(
uint
max_num_labels
)
{
asm_x64_t
*
asm_x64_new
(
uint
max_num_labels
)
{
asm_x64_t
*
as
;
asm_x64_t
*
as
;
as
=
m_new
(
asm_x64_t
,
1
);
as
=
m_new0
(
asm_x64_t
,
1
);
as
->
pass
=
0
;
as
->
code_offset
=
0
;
as
->
code_size
=
0
;
as
->
code_base
=
NULL
;
as
->
max_num_labels
=
max_num_labels
;
as
->
max_num_labels
=
max_num_labels
;
as
->
label_offsets
=
m_new
(
int
,
max_num_labels
);
as
->
label_offsets
=
m_new
(
int
,
max_num_labels
);
as
->
num_locals
=
0
;
return
as
;
return
as
;
}
}
...
@@ -170,17 +165,17 @@ void asm_x64_free(asm_x64_t *as, bool free_code) {
...
@@ -170,17 +165,17 @@ void asm_x64_free(asm_x64_t *as, bool free_code) {
m_del_obj
(
asm_x64_t
,
as
);
m_del_obj
(
asm_x64_t
,
as
);
}
}
void
asm_x64_start_pass
(
asm_x64_t
*
as
,
int
pass
)
{
void
asm_x64_start_pass
(
asm_x64_t
*
as
,
u
int
pass
)
{
as
->
pass
=
pass
;
as
->
pass
=
pass
;
as
->
code_offset
=
0
;
as
->
code_offset
=
0
;
if
(
pass
==
ASM_X64_PASS_
2
)
{
if
(
pass
==
ASM_X64_PASS_
COMPUTE
)
{
// reset all labels
// reset all labels
memset
(
as
->
label_offsets
,
-
1
,
as
->
max_num_labels
*
sizeof
(
int
));
memset
(
as
->
label_offsets
,
-
1
,
as
->
max_num_labels
*
sizeof
(
int
));
}
}
}
}
void
asm_x64_end_pass
(
asm_x64_t
*
as
)
{
void
asm_x64_end_pass
(
asm_x64_t
*
as
)
{
if
(
as
->
pass
==
ASM_X64_PASS_
2
)
{
if
(
as
->
pass
==
ASM_X64_PASS_
COMPUTE
)
{
// calculate size of code in bytes
// calculate size of code in bytes
as
->
code_size
=
as
->
code_offset
;
as
->
code_size
=
as
->
code_offset
;
//as->code_base = m_new(byte, as->code_size); need to allocale executable memory
//as->code_base = m_new(byte, as->code_size); need to allocale executable memory
...
@@ -204,7 +199,7 @@ void asm_x64_end_pass(asm_x64_t *as) {
...
@@ -204,7 +199,7 @@ void asm_x64_end_pass(asm_x64_t *as) {
// all functions must go through this one to emit bytes
// all functions must go through this one to emit bytes
STATIC
byte
*
asm_x64_get_cur_to_write_bytes
(
asm_x64_t
*
as
,
int
num_bytes_to_write
)
{
STATIC
byte
*
asm_x64_get_cur_to_write_bytes
(
asm_x64_t
*
as
,
int
num_bytes_to_write
)
{
//printf("emit %d\n", num_bytes_to_write);
//printf("emit %d\n", num_bytes_to_write);
if
(
as
->
pass
<
ASM_X64_PASS_
3
)
{
if
(
as
->
pass
<
ASM_X64_PASS_
EMIT
)
{
as
->
code_offset
+=
num_bytes_to_write
;
as
->
code_offset
+=
num_bytes_to_write
;
return
as
->
dummy_data
;
return
as
->
dummy_data
;
}
else
{
}
else
{
...
@@ -367,6 +362,15 @@ void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r
...
@@ -367,6 +362,15 @@ void asm_x64_mov_i64_to_r64_optimised(asm_x64_t *as, int64_t src_i64, int dest_r
}
}
}
}
// src_i64 is stored as a full word in the code, and aligned to machine-word boundary
void
asm_x64_mov_i64_to_r64_aligned
(
asm_x64_t
*
as
,
int64_t
src_i64
,
int
dest_r64
)
{
// mov instruction uses 2 bytes for the instruction, before the i64
while
(((
as
->
code_offset
+
2
)
&
(
WORD_SIZE
-
1
))
!=
0
)
{
asm_x64_nop
(
as
);
}
asm_x64_mov_i64_to_r64
(
as
,
src_i64
,
dest_r64
);
}
void
asm_x64_mov_i32_to_disp
(
asm_x64_t
*
as
,
int
src_i32
,
int
dest_r32
,
int
dest_disp
)
void
asm_x64_mov_i32_to_disp
(
asm_x64_t
*
as
,
int
src_i32
,
int
dest_r32
,
int
dest_disp
)
{
{
assert
(
0
);
assert
(
0
);
...
@@ -487,12 +491,12 @@ void asm_x64_setcc_r8(asm_x64_t *as, int jcc_type, int dest_r8) {
...
@@ -487,12 +491,12 @@ void asm_x64_setcc_r8(asm_x64_t *as, int jcc_type, int dest_r8) {
void
asm_x64_label_assign
(
asm_x64_t
*
as
,
int
label
)
{
void
asm_x64_label_assign
(
asm_x64_t
*
as
,
int
label
)
{
assert
(
label
<
as
->
max_num_labels
);
assert
(
label
<
as
->
max_num_labels
);
if
(
as
->
pass
==
ASM_X64_PASS_
2
)
{
if
(
as
->
pass
<
ASM_X64_PASS_
EMIT
)
{
// assign label offset
// assign label offset
assert
(
as
->
label_offsets
[
label
]
==
-
1
);
assert
(
as
->
label_offsets
[
label
]
==
-
1
);
as
->
label_offsets
[
label
]
=
as
->
code_offset
;
as
->
label_offsets
[
label
]
=
as
->
code_offset
;
}
else
if
(
as
->
pass
==
ASM_X64_PASS_3
)
{
}
else
{
// ensure label offset has not changed from PASS_
2
to PASS_
3
// ensure label offset has not changed from PASS_
COMPUTE
to PASS_
EMIT
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
//printf("l%d: (at %d=%ld)\n", label, as->label_offsets[label], as->code_offset);
assert
(
as
->
label_offsets
[
label
]
==
as
->
code_offset
);
assert
(
as
->
label_offsets
[
label
]
==
as
->
code_offset
);
}
}
...
...
py/asmx64.h
View file @
36db6bcf
...
@@ -24,9 +24,8 @@
...
@@ -24,9 +24,8 @@
* THE SOFTWARE.
* THE SOFTWARE.
*/
*/
#define ASM_X64_PASS_1 (1)
#define ASM_X64_PASS_COMPUTE (1)
#define ASM_X64_PASS_2 (2)
#define ASM_X64_PASS_EMIT (2)
#define ASM_X64_PASS_3 (3)
#define REG_RAX (0)
#define REG_RAX (0)
#define REG_RCX (1)
#define REG_RCX (1)
...
@@ -54,7 +53,7 @@ typedef struct _asm_x64_t asm_x64_t;
...
@@ -54,7 +53,7 @@ typedef struct _asm_x64_t asm_x64_t;
asm_x64_t
*
asm_x64_new
(
uint
max_num_labels
);
asm_x64_t
*
asm_x64_new
(
uint
max_num_labels
);
void
asm_x64_free
(
asm_x64_t
*
as
,
bool
free_code
);
void
asm_x64_free
(
asm_x64_t
*
as
,
bool
free_code
);
void
asm_x64_start_pass
(
asm_x64_t
*
as
,
int
pass
);
void
asm_x64_start_pass
(
asm_x64_t
*
as
,
u
int
pass
);
void
asm_x64_end_pass
(
asm_x64_t
*
as
);
void
asm_x64_end_pass
(
asm_x64_t
*
as
);
uint
asm_x64_get_code_size
(
asm_x64_t
*
as
);
uint
asm_x64_get_code_size
(
asm_x64_t
*
as
);
void
*
asm_x64_get_code
(
asm_x64_t
*
as
);
void
*
asm_x64_get_code
(
asm_x64_t
*
as
);
...
@@ -71,6 +70,7 @@ void asm_x64_mov_i32_to_r64(asm_x64_t* as, int src_i32, int dest_r64);
...
@@ -71,6 +70,7 @@ void asm_x64_mov_i32_to_r64(asm_x64_t* as, int src_i32, int dest_r64);
void
asm_x64_mov_i64_to_r64
(
asm_x64_t
*
as
,
int64_t
src_i64
,
int
dest_r64
);
void
asm_x64_mov_i64_to_r64
(
asm_x64_t
*
as
,
int64_t
src_i64
,
int
dest_r64
);
void
asm_x64_mov_i32_to_disp
(
asm_x64_t
*
as
,
int
src_i32
,
int
dest_r32
,
int
dest_disp
);
void
asm_x64_mov_i32_to_disp
(
asm_x64_t
*
as
,
int
src_i32
,
int
dest_r32
,
int
dest_disp
);
void
asm_x64_mov_i64_to_r64_optimised
(
asm_x64_t
*
as
,
int64_t
src_i64
,
int
dest_r64
);
void
asm_x64_mov_i64_to_r64_optimised
(
asm_x64_t
*
as
,
int64_t
src_i64
,
int
dest_r64
);
void
asm_x64_mov_i64_to_r64_aligned
(
asm_x64_t
*
as
,
int64_t
src_i64
,
int
dest_r64
);
void
asm_x64_xor_r64_to_r64
(
asm_x64_t
*
as
,
int
src_r64
,
int
dest_r64
);
void
asm_x64_xor_r64_to_r64
(
asm_x64_t
*
as
,
int
src_r64
,
int
dest_r64
);
void
asm_x64_add_r64_to_r64
(
asm_x64_t
*
as
,
int
src_r64
,
int
dest_r64
);
void
asm_x64_add_r64_to_r64
(
asm_x64_t
*
as
,
int
src_r64
,
int
dest_r64
);
void
asm_x64_add_i32_to_r32
(
asm_x64_t
*
as
,
int
src_i32
,
int
dest_r32
);
void
asm_x64_add_i32_to_r32
(
asm_x64_t
*
as
,
int
src_i32
,
int
dest_r32
);
...
...
py/compile.c
View file @
36db6bcf
...
@@ -994,7 +994,7 @@ void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) {
...
@@ -994,7 +994,7 @@ void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) {
// leaves function object on stack
// leaves function object on stack
// returns function name
// returns function name
qstr
compile_funcdef_helper
(
compiler_t
*
comp
,
mp_parse_node_struct_t
*
pns
,
uint
emit_options
)
{
qstr
compile_funcdef_helper
(
compiler_t
*
comp
,
mp_parse_node_struct_t
*
pns
,
uint
emit_options
)
{
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
// create a new scope for this function
// create a new scope for this function
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_FUNCTION
,
(
mp_parse_node_t
)
pns
,
emit_options
);
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_FUNCTION
,
(
mp_parse_node_t
)
pns
,
emit_options
);
// store the function scope so the compiling function can use it at each pass
// store the function scope so the compiling function can use it at each pass
...
@@ -1043,7 +1043,7 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
...
@@ -1043,7 +1043,7 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint
// leaves class object on stack
// leaves class object on stack
// returns class name
// returns class name
qstr
compile_classdef_helper
(
compiler_t
*
comp
,
mp_parse_node_struct_t
*
pns
,
uint
emit_options
)
{
qstr
compile_classdef_helper
(
compiler_t
*
comp
,
mp_parse_node_struct_t
*
pns
,
uint
emit_options
)
{
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
// create a new scope for this class
// create a new scope for this class
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_CLASS
,
(
mp_parse_node_t
)
pns
,
emit_options
);
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_CLASS
,
(
mp_parse_node_t
)
pns
,
emit_options
);
// store the class scope so the compiling function can use it at each pass
// store the class scope so the compiling function can use it at each pass
...
@@ -1510,7 +1510,7 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
...
@@ -1510,7 +1510,7 @@ void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
}
void
compile_global_stmt
(
compiler_t
*
comp
,
mp_parse_node_struct_t
*
pns
)
{
void
compile_global_stmt
(
compiler_t
*
comp
,
mp_parse_node_struct_t
*
pns
)
{
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
if
(
MP_PARSE_NODE_IS_LEAF
(
pns
->
nodes
[
0
]))
{
if
(
MP_PARSE_NODE_IS_LEAF
(
pns
->
nodes
[
0
]))
{
scope_declare_global
(
comp
->
scope_cur
,
MP_PARSE_NODE_LEAF_ARG
(
pns
->
nodes
[
0
]));
scope_declare_global
(
comp
->
scope_cur
,
MP_PARSE_NODE_LEAF_ARG
(
pns
->
nodes
[
0
]));
}
else
{
}
else
{
...
@@ -1524,7 +1524,7 @@ void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
...
@@ -1524,7 +1524,7 @@ void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
}
void
compile_nonlocal_stmt
(
compiler_t
*
comp
,
mp_parse_node_struct_t
*
pns
)
{
void
compile_nonlocal_stmt
(
compiler_t
*
comp
,
mp_parse_node_struct_t
*
pns
)
{
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
if
(
MP_PARSE_NODE_IS_LEAF
(
pns
->
nodes
[
0
]))
{
if
(
MP_PARSE_NODE_IS_LEAF
(
pns
->
nodes
[
0
]))
{
scope_declare_nonlocal
(
comp
->
scope_cur
,
MP_PARSE_NODE_LEAF_ARG
(
pns
->
nodes
[
0
]));
scope_declare_nonlocal
(
comp
->
scope_cur
,
MP_PARSE_NODE_LEAF_ARG
(
pns
->
nodes
[
0
]));
}
else
{
}
else
{
...
@@ -2056,7 +2056,7 @@ void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
...
@@ -2056,7 +2056,7 @@ void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
&& MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1], PN_trailer_paren)
&& MP_PARSE_NODE_IS_STRUCT_KIND(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1], PN_trailer_paren)
&& MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[2])
&& MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[2])
) {
) {
if (comp->pass == PASS_
1
) {
if (comp->pass ==
MP_
PASS_
SCOPE
) {
qstr const_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
qstr const_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
if (!MP_PARSE_NODE_IS_SMALL_INT(((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1])->nodes[0])) {
if (!MP_PARSE_NODE_IS_SMALL_INT(((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pns1->nodes[0])->nodes[1])->nodes[0])) {
...
@@ -2153,7 +2153,7 @@ void compile_lambdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
...
@@ -2153,7 +2153,7 @@ void compile_lambdef(compiler_t *comp, mp_parse_node_struct_t *pns) {
//mp_parse_node_t pn_params = pns->nodes[0];
//mp_parse_node_t pn_params = pns->nodes[0];
//mp_parse_node_t pn_body = pns->nodes[1];
//mp_parse_node_t pn_body = pns->nodes[1];
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
// create a new scope for this lambda
// create a new scope for this lambda
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_LAMBDA
,
(
mp_parse_node_t
)
pns
,
comp
->
scope_cur
->
emit_options
);
scope_t
*
s
=
scope_new_and_link
(
comp
,
SCOPE_LAMBDA
,
(
mp_parse_node_t
)
pns
,
comp
->
scope_cur
->
emit_options
);
// store the lambda scope so the compiling function (this one) can use it at each pass
// store the lambda scope so the compiling function (this one) can use it at each pass
...
@@ -2499,7 +2499,7 @@ void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_
...
@@ -2499,7 +2499,7 @@ void compile_comprehension(compiler_t *comp, mp_parse_node_struct_t *pns, scope_
assert
(
MP_PARSE_NODE_IS_STRUCT_KIND
(
pns
->
nodes
[
1
],
PN_comp_for
));
assert
(
MP_PARSE_NODE_IS_STRUCT_KIND
(
pns
->
nodes
[
1
],
PN_comp_for
));
mp_parse_node_struct_t
*
pns_comp_for
=
(
mp_parse_node_struct_t
*
)
pns
->
nodes
[
1
];
mp_parse_node_struct_t
*
pns_comp_for
=
(
mp_parse_node_struct_t
*
)
pns
->
nodes
[
1
];
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
// create a new scope for this comprehension
// create a new scope for this comprehension
scope_t
*
s
=
scope_new_and_link
(
comp
,
kind
,
(
mp_parse_node_t
)
pns
,
comp
->
scope_cur
->
emit_options
);
scope_t
*
s
=
scope_new_and_link
(
comp
,
kind
,
(
mp_parse_node_t
)
pns
,
comp
->
scope_cur
->
emit_options
);
// store the comprehension scope so the compiling function (this one) can use it at each pass
// store the comprehension scope so the compiling function (this one) can use it at each pass
...
@@ -3020,7 +3020,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -3020,7 +3020,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
comp
->
next_label
=
1
;
comp
->
next_label
=
1
;
EMIT_ARG
(
start_pass
,
pass
,
scope
);
EMIT_ARG
(
start_pass
,
pass
,
scope
);
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
// reset maximum stack sizes in scope
// reset maximum stack sizes in scope
// they will be computed in this first pass
// they will be computed in this first pass
scope
->
stack_size
=
0
;
scope
->
stack_size
=
0
;
...
@@ -3028,7 +3028,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -3028,7 +3028,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
}
}
#if MICROPY_EMIT_CPYTHON
#if MICROPY_EMIT_CPYTHON
if
(
comp
->
pass
==
PASS_
3
)
{
if
(
comp
->
pass
==
MP_
PASS_
EMIT
)
{
scope_print_info
(
scope
);
scope_print_info
(
scope
);
}
}
#endif
#endif
...
@@ -3053,7 +3053,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -3053,7 +3053,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
// work out number of parameters, keywords and default parameters, and add them to the id_info array
// work out number of parameters, keywords and default parameters, and add them to the id_info array
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
comp
->
have_star
=
false
;
comp
->
have_star
=
false
;
apply_to_single_or_list
(
comp
,
pns
->
nodes
[
1
],
PN_typedargslist
,
compile_scope_func_param
);
apply_to_single_or_list
(
comp
,
pns
->
nodes
[
1
],
PN_typedargslist
,
compile_scope_func_param
);
}
}
...
@@ -3073,7 +3073,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -3073,7 +3073,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
// work out number of parameters, keywords and default parameters, and add them to the id_info array
// work out number of parameters, keywords and default parameters, and add them to the id_info array
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
// must be done before compiling the body so that arguments are numbered first (for LOAD_FAST etc)
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
comp
->
have_star
=
false
;
comp
->
have_star
=
false
;
apply_to_single_or_list
(
comp
,
pns
->
nodes
[
0
],
PN_varargslist
,
compile_scope_lambda_param
);
apply_to_single_or_list
(
comp
,
pns
->
nodes
[
0
],
PN_varargslist
,
compile_scope_lambda_param
);
}
}
...
@@ -3104,7 +3104,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -3104,7 +3104,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
#else
#else
qstr
qstr_arg
=
MP_QSTR_
;
qstr
qstr_arg
=
MP_QSTR_
;
#endif
#endif
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
bool
added
;
bool
added
;
id_info_t
*
id_info
=
scope_find_or_add_id
(
comp
->
scope_cur
,
qstr_arg
,
&
added
);
id_info_t
*
id_info
=
scope_find_or_add_id
(
comp
->
scope_cur
,
qstr_arg
,
&
added
);
assert
(
added
);
assert
(
added
);
...
@@ -3141,7 +3141,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -3141,7 +3141,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
mp_parse_node_struct_t
*
pns
=
(
mp_parse_node_struct_t
*
)
scope
->
pn
;
mp_parse_node_struct_t
*
pns
=
(
mp_parse_node_struct_t
*
)
scope
->
pn
;
assert
(
MP_PARSE_NODE_STRUCT_KIND
(
pns
)
==
PN_classdef
);
assert
(
MP_PARSE_NODE_STRUCT_KIND
(
pns
)
==
PN_classdef
);
if
(
comp
->
pass
==
PASS_
1
)
{
if
(
comp
->
pass
==
MP_
PASS_
SCOPE
)
{
bool
added
;
bool
added
;
id_info_t
*
id_info
=
scope_find_or_add_id
(
scope
,
MP_QSTR___class__
,
&
added
);
id_info_t
*
id_info
=
scope_find_or_add_id
(
scope
,
MP_QSTR___class__
,
&
added
);
assert
(
added
);
assert
(
added
);
...
@@ -3177,6 +3177,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
...
@@ -3177,6 +3177,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
}
}
#if MICROPY_EMIT_INLINE_THUMB
#if MICROPY_EMIT_INLINE_THUMB
// requires 3 passes: SCOPE, CODE_SIZE, EMIT
STATIC
void
compile_scope_inline_asm
(
compiler_t
*
comp
,
scope_t
*
scope
,
pass_kind_t
pass
)
{
STATIC
void
compile_scope_inline_asm
(
compiler_t
*
comp
,
scope_t
*
scope
,
pass_kind_t
pass
)
{
comp
->
pass
=
pass
;
comp
->
pass
=
pass
;
comp
->
scope_cur
=
scope
;
comp
->
scope_cur
=
scope
;
...
@@ -3187,7 +3188,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
...
@@ -3187,7 +3188,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
return
;
return
;
}
}
if
(
comp
->
pass
>
PASS_
1
)
{
if
(
comp
->
pass
>
MP_
PASS_
SCOPE
)
{
EMIT_INLINE_ASM_ARG
(
start_pass
,
comp
->
pass
,
comp
->
scope_cur
);
EMIT_INLINE_ASM_ARG
(
start_pass
,
comp
->
pass
,
comp
->
scope_cur
);
}
}
...
@@ -3199,7 +3200,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
...
@@ -3199,7 +3200,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
//qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
//qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
// parameters are in pns->nodes[1]
// parameters are in pns->nodes[1]
if
(
comp
->
pass
==
PASS_
2
)
{
if
(
comp
->
pass
==
MP_
PASS_
CODE_SIZE
)
{
mp_parse_node_t
*
pn_params
;
mp_parse_node_t
*
pn_params
;
int
n_params
=
list_get
(
&
pns
->
nodes
[
1
],
PN_typedargslist
,
&
pn_params
);
int
n_params
=
list_get
(
&
pns
->
nodes
[
1
],
PN_typedargslist
,
&
pn_params
);
scope
->
num_pos_args
=
EMIT_INLINE_ASM_ARG
(
count_params
,
n_params
,
pn_params
);
scope
->
num_pos_args
=
EMIT_INLINE_ASM_ARG
(
count_params
,
n_params
,
pn_params
);
...
@@ -3212,7 +3213,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
...
@@ -3212,7 +3213,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
int
num
=
list_get
(
&
pn_body
,
PN_suite_block_stmts
,
&
nodes
);
int
num
=
list_get
(
&
pn_body
,
PN_suite_block_stmts
,
&
nodes
);
/*
/*
if (comp->pass == PASS_
3
) {
if (comp->pass ==
MP_
PASS_
EMIT
) {
//printf("----\n");
//printf("----\n");
scope_print_info(scope);
scope_print_info(scope);
}
}
...
@@ -3250,7 +3251,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
...
@@ -3250,7 +3251,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
return
;
return
;
}
}
uint
lab
=
comp_next_label
(
comp
);
uint
lab
=
comp_next_label
(
comp
);
if
(
pass
>
PASS_
1
)
{
if
(
pass
>
MP_
PASS_
SCOPE
)
{
EMIT_INLINE_ASM_ARG
(
label
,
lab
,
MP_PARSE_NODE_LEAF_ARG
(
pn_arg
[
0
]));
EMIT_INLINE_ASM_ARG
(
label
,
lab
,
MP_PARSE_NODE_LEAF_ARG
(
pn_arg
[
0
]));
}
}
}
else
if
(
op
==
MP_QSTR_align
)
{
}
else
if
(
op
==
MP_QSTR_align
)
{
...
@@ -3258,7 +3259,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
...
@@ -3258,7 +3259,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
compile_syntax_error
(
comp
,
nodes
[
i