Skip to content

Commit e24e176

Browse files
committed
Support i686
1 parent c6fa882 commit e24e176

1 file changed

Lines changed: 48 additions & 0 deletions

File tree

Python/jit.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,54 @@ _emit_load_fast_borrow(unsigned char *code, int reg_variant, int oparg)
731731
code[10] = 0x01; // imm8 = 1
732732
}
733733

734+
#elif defined(_M_IX86) || defined(__i386__)
735+
736+
// i686: movl 8(%esp),%ecx ; movl off(%ecx),%ecx ; orl $1,%ecx ;
737+
// movl %ecx,cache(%esp) (17 bytes, no data)
738+
// i686 does not use preserve_none (unsupported by MSVC).
739+
// Stack layout: 8(%esp)=frame, 20/24/28(%esp)=cache0/1/2
740+
#define LOAD_FAST_BORROW_CODE_SIZE 17
741+
742+
// Stack offsets for cache slots (from %esp)
743+
static const uint8_t _i686_cache_offsets[3] = {
744+
20, // c0 (r01)
745+
24, // c1 (r12)
746+
28, // c2 (r23)
747+
};
748+
749+
static void
750+
_emit_load_fast_borrow(unsigned char *code, int reg_variant, int oparg)
751+
{
752+
uint32_t byte_offset = (uint32_t)(offsetof(_PyInterpreterFrame, localsplus)
753+
+ (unsigned)oparg * sizeof(_PyStackRef));
754+
uint8_t cache_off = _i686_cache_offsets[reg_variant];
755+
756+
// movl 8(%esp), %ecx — load frame
757+
code[0] = 0x8B; // MOV r32, r/m32
758+
code[1] = 0x4C; // ModRM: mod=01, reg=ecx(001), r/m=100(SIB)
759+
code[2] = 0x24; // SIB: scale=00, index=100(none), base=100(esp)
760+
code[3] = 0x08; // disp8 = 8
761+
762+
// movl byte_offset(%ecx), %ecx — load localsplus[oparg]
763+
code[4] = 0x8B; // MOV r32, r/m32
764+
code[5] = 0x89; // ModRM: mod=10(disp32), reg=ecx(001), r/m=001(ecx)
765+
memcpy(code + 6, &byte_offset, 4); // disp32
766+
767+
// orl $1, %ecx — borrow tag
768+
code[10] = 0x83; // OR r/m32, imm8
769+
code[11] = 0xC9; // ModRM: mod=11, reg=001(/1), r/m=001(ecx)
770+
code[12] = 0x01; // imm8 = 1
771+
772+
// movl %ecx, cache_off(%esp) — write to cache slot
773+
code[13] = 0x89; // MOV r/m32, r32
774+
code[14] = 0x4C; // ModRM: mod=01, reg=ecx(001), r/m=100(SIB)
775+
code[15] = 0x24; // SIB: scale=00, index=100(none), base=100(esp)
776+
code[16] = cache_off; // disp8
777+
778+
}
779+
780+
#else
781+
# error "unsupported architecture for manual _LOAD_FAST_BORROW emission"
734782
#endif
735783

736784
// Compiles executor in-place. Don't forget to call _PyJIT_Free later!

0 commit comments

Comments
 (0)