summaryrefslogtreecommitdiff
path: root/py/asmx86.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-04-06 22:38:53 +0100
committerDamien George <damien.p.george@gmail.com>2015-04-07 22:43:28 +0100
commit9988618e0e0f5c319e31b135d993e22efb593093 (patch)
treed89d8df392ce2669c9e516a05b11742e72dc8cf2 /py/asmx86.c
parent18bd51707c218137005cd73cb5a35ebfe2bccd6e (diff)
py: Implement full func arg passing for native emitter.
This patch gets full function argument passing working with native emitter. Includes named args, keyword args, default args, var args and var keyword args. Fully Python compliant. It reuses the bytecode mp_setup_code_state function to do all the hard work. This function is slightly adjusted to accommodate native calls, and the native emitter is forced a bit to emit similar prelude and code-info as bytecode.
Diffstat (limited to 'py/asmx86.c')
-rw-r--r--py/asmx86.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/py/asmx86.c b/py/asmx86.c
index 3de2f12aa..8a4383c82 100644
--- a/py/asmx86.c
+++ b/py/asmx86.c
@@ -162,6 +162,10 @@ STATIC byte *asm_x86_get_cur_to_write_bytes(asm_x86_t *as, int num_bytes_to_writ
}
}
+mp_uint_t asm_x86_get_code_pos(asm_x86_t *as) {
+ return as->code_offset;
+}
+
mp_uint_t asm_x86_get_code_size(asm_x86_t *as) {
return as->code_size;
}
@@ -196,6 +200,21 @@ STATIC void asm_x86_write_word32(asm_x86_t *as, int w32) {
c[3] = IMM32_L3(w32);
}
+// align must be a multiple of 2
+void asm_x86_align(asm_x86_t* as, mp_uint_t align) {
+ // TODO fill unused data with NOPs?
+ as->code_offset = (as->code_offset + align - 1) & (~(align - 1));
+}
+
+void asm_x86_data(asm_x86_t* as, mp_uint_t bytesize, mp_uint_t val) {
+ byte *c = asm_x86_get_cur_to_write_bytes(as, bytesize);
+ // machine is little endian
+ for (uint i = 0; i < bytesize; i++) {
+ *c++ = val;
+ val >>= 8;
+ }
+}
+
STATIC void asm_x86_write_r32_disp(asm_x86_t *as, int r32, int disp_r32, int disp_offset) {
assert(disp_r32 != ASM_X86_REG_ESP);
@@ -541,7 +560,13 @@ void asm_x86_push_local_addr(asm_x86_t *as, int local_num, int temp_r32)
void asm_x86_call_ind(asm_x86_t *as, void *ptr, mp_uint_t n_args, int temp_r32) {
// TODO align stack on 16-byte boundary before the call
- assert(n_args <= 3);
+ assert(n_args <= 5);
+ if (n_args > 4) {
+ asm_x86_push_r32(as, ASM_X86_REG_ARG_5);
+ }
+ if (n_args > 3) {
+ asm_x86_push_r32(as, ASM_X86_REG_ARG_4);
+ }
if (n_args > 2) {
asm_x86_push_r32(as, ASM_X86_REG_ARG_3);
}