5454#define OPCODE_LEA_MEM_TO_R32 (0x8d) /* /r */
5555#define OPCODE_XOR_R32_TO_RM32 (0x31) /* /r */
5656#define OPCODE_ADD_R32_TO_RM32 (0x01)
57- // #define OPCODE_ADD_I32_TO_RM32 (0x81) /* /0 */
58- // #define OPCODE_ADD_I8_TO_RM32 (0x83) /* /0 */
57+ #define OPCODE_ADD_I32_TO_RM32 (0x81) /* /0 */
58+ #define OPCODE_ADD_I8_TO_RM32 (0x83) /* /0 */
5959//#define OPCODE_SUB_R32_FROM_RM32 (0x29)
6060#define OPCODE_SUB_I32_FROM_RM32 (0x81) /* /5 */
6161#define OPCODE_SUB_I8_FROM_RM32 (0x83) /* /5 */
@@ -275,21 +275,17 @@ void asm_x86_add_r32_to_r32(asm_x86_t *as, int src_r32, int dest_r32) {
275275 asm_x86_write_byte_2 (as , OPCODE_ADD_R32_TO_RM32 , MODRM_R32 (src_r32 ) | MODRM_RM_REG | MODRM_RM_R32 (dest_r32 ));
276276}
277277
278- #if 0
279- void asm_x86_add_i32_to_r32 (asm_x86_t * as , int src_i32 , int dest_r32 )
280- {
281- if (SIGNED_FIT8 (src_i32 ))
282- {
278+ void asm_x86_add_i32_to_r32 (asm_x86_t * as , int src_i32 , int dest_r32 ) {
279+ if (SIGNED_FIT8 (src_i32 )) {
283280 asm_x86_write_byte_2 (as , OPCODE_ADD_I8_TO_RM32 , MODRM_R32 (0 ) | MODRM_RM_REG | MODRM_RM_R32 (dest_r32 ));
284281 asm_x86_write_byte_1 (as , src_i32 & 0xff );
285- }
286- else
287- {
282+ } else {
288283 asm_x86_write_byte_2 (as , OPCODE_ADD_I32_TO_RM32 , MODRM_R32 (0 ) | MODRM_RM_REG | MODRM_RM_R32 (dest_r32 ));
289284 asm_x86_write_word32 (as , src_i32 );
290285 }
291286}
292287
288+ #if 0
293289void asm_x86_sub_r32_from_r32 (asm_x86_t * as , int src_r32 , int dest_r32 ) {
294290 asm_x86_write_byte_2 (as , OPCODE_SUB_R32_FROM_RM32 , MODRM_R32 (src_r32 ) | MODRM_RM_REG | MODRM_RM_R32 (dest_r32 ));
295291}
@@ -419,29 +415,33 @@ void asm_x86_entry(asm_x86_t *as, mp_uint_t num_locals) {
419415 asm_x86_mov_r32_to_r32 (as , REG_ESP , REG_EBP );
420416 asm_x86_sub_i32_from_r32 (as , num_locals * WORD_SIZE , REG_ESP );
421417 asm_x86_push_r32 (as , REG_EBX );
418+ asm_x86_push_r32 (as , REG_ESI );
419+ asm_x86_push_r32 (as , REG_EDI );
420+ // TODO align stack on 16-byte boundary
422421 as -> num_locals = num_locals ;
423422}
424423
425424void asm_x86_exit (asm_x86_t * as ) {
425+ asm_x86_pop_r32 (as , REG_EDI );
426+ asm_x86_pop_r32 (as , REG_ESI );
426427 asm_x86_pop_r32 (as , REG_EBX );
427428 asm_x86_write_byte_1 (as , OPCODE_LEAVE );
428429 asm_x86_ret (as );
429430}
430431
431432#if 0
432433void asm_x86_push_arg (asm_x86_t * as , int src_arg_num ) {
433- assert (0 );
434- asm_x86_push_disp (as , REG_EBP , 8 + src_arg_num * WORD_SIZE );
434+ asm_x86_push_disp (as , REG_EBP , 2 * WORD_SIZE + src_arg_num * WORD_SIZE );
435435}
436+ #endif
436437
437438void asm_x86_mov_arg_to_r32 (asm_x86_t * as , int src_arg_num , int dest_r32 ) {
438- assert (0 );
439- //asm_x86_mov_disp_to_r32(as, REG_EBP, 8 + src_arg_num * WORD_SIZE, dest_r32);
439+ asm_x86_mov_disp_to_r32 (as , REG_EBP , 2 * WORD_SIZE + src_arg_num * WORD_SIZE , dest_r32 );
440440}
441441
442+ #if 0
442443void asm_x86_mov_r32_to_arg (asm_x86_t * as , int src_r32 , int dest_arg_num ) {
443- assert (0 );
444- //asm_x86_mov_r32_to_disp(as, src_r32, REG_EBP, 8 + dest_arg_num * WORD_SIZE);
444+ asm_x86_mov_r32_to_disp (as , src_r32 , REG_EBP , 2 * WORD_SIZE + dest_arg_num * WORD_SIZE );
445445}
446446#endif
447447
@@ -491,6 +491,7 @@ void asm_x86_push_local_addr(asm_x86_t *as, int local_num, int temp_r32)
491491#endif
492492
493493void asm_x86_call_ind (asm_x86_t * as , void * ptr , mp_uint_t n_args , int temp_r32 ) {
494+ // TODO align stack on 16-byte boundary before the call
494495 assert (n_args <= 3 );
495496 if (n_args > 2 ) {
496497 asm_x86_push_r32 (as , REG_ARG_3 );
@@ -515,6 +516,11 @@ void asm_x86_call_ind(asm_x86_t *as, void *ptr, mp_uint_t n_args, int temp_r32)
515516 asm_x86_write_byte_1(as, OPCODE_CALL_REL32);
516517 asm_x86_write_word32(as, ptr - (void*)(as->code_base + as->code_offset + 4));
517518 */
519+
520+ // the caller must clean up the stack
521+ if (n_args > 0 ) {
522+ asm_x86_add_i32_to_r32 (as , WORD_SIZE * n_args , REG_ESP );
523+ }
518524}
519525
520526#endif // MICROPY_EMIT_X86
0 commit comments