diff --git a/arm64-gen.c b/arm64-gen.c index e5f17f62..162ce2fe 100644 --- a/arm64-gen.c +++ b/arm64-gen.c @@ -302,7 +302,7 @@ static void arm64_spoff(int reg, uint64_t off) o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(31) | ARM64_RD(reg) | ARM64_IMM12(off)); else { arm64_movimm(30, off); - o(ARM64_ADD_REG | ARM64_SF(1) | ARM64_RM(30) | ARM64_RN(31) | ARM64_RD(reg) | (sub << 31)); + o(ARM64_ADD_REG | ARM64_SF(1) | ARM64_RM(30) | ARM64_RN(31) | ARM64_RD(reg) | (sub << 30)); } } @@ -521,15 +521,15 @@ ST_FUNC void load(int r, SValue *sv) int svtt = sv->type.t; int svr = sv->r & ~(VT_BOUNDED | VT_NONCONST); int svrv = svr & VT_VALMASK; - uint64_t svcul = (uint32_t)sv->c.i; - svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul; + uint64_t svcul = sv->c.i; + uint64_t svcoff = (uint64_t)(int64_t)(int32_t)sv->c.i; if (svr == (VT_LOCAL | VT_LVAL)) { if (IS_FREG(r)) - arm64_ldrv(arm64_type_size(svtt), fltr(r), 29, svcul); + arm64_ldrv(arm64_type_size(svtt), fltr(r), 29, svcoff); else arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt), - intr(r), 29, svcul); + intr(r), 29, svcoff); return; } @@ -563,13 +563,13 @@ ST_FUNC void load(int r, SValue *sv) if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { arm64_sym(30, sv->sym, // use x30 for address - arm64_check_offset(0, arm64_type_size(svtt), svcul)); + arm64_check_offset(0, arm64_type_size(svtt), svcoff)); if (IS_FREG(r)) arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, - arm64_check_offset(1, arm64_type_size(svtt), svcul)); + arm64_check_offset(1, arm64_type_size(svtt), svcoff)); else arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30, - arm64_check_offset(1, arm64_type_size(svtt), svcul)); + arm64_check_offset(1, arm64_type_size(svtt), svcoff)); return; } @@ -600,10 +600,10 @@ ST_FUNC void load(int r, SValue *sv) } if (svr == VT_LOCAL) { - if (-svcul < 0x1000) - o(0xd10003a0 | intr(r) | -svcul << 10); // sub x(r),x29,#... + if (-svcoff < 0x1000) + o(0xd10003a0 | intr(r) | -svcoff << 10); // sub x(r),x29,#... else { - arm64_movimm(30, -svcul); // use x30 for offset + arm64_movimm(30, -svcoff); // use x30 for offset o(0xcb0003a0 | intr(r) | (uint32_t)30 << 16); // sub x(r),x29,x30 } return; @@ -619,7 +619,7 @@ ST_FUNC void load(int r, SValue *sv) } if (svr == (VT_LLOCAL | VT_LVAL)) { - arm64_ldrx(0, 3, 30, 29, svcul); // use x30 for offset + arm64_ldrx(0, 3, 30, 29, svcoff); // use x30 for offset if (IS_FREG(r)) arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0); else @@ -642,14 +642,13 @@ ST_FUNC void store(int r, SValue *sv) int svtt = sv->type.t; int svr = sv->r & ~VT_BOUNDED; int svrv = svr & VT_VALMASK; - uint64_t svcul = (uint32_t)sv->c.i; - svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul; + uint64_t svcoff = (uint64_t)(int64_t)(int32_t)sv->c.i; if (svr == (VT_LOCAL | VT_LVAL)) { if (IS_FREG(r)) - arm64_strv(arm64_type_size(svtt), fltr(r), 29, svcul); + arm64_strv(arm64_type_size(svtt), fltr(r), 29, svcoff); else - arm64_strx(arm64_type_size(svtt), intr(r), 29, svcul); + arm64_strx(arm64_type_size(svtt), intr(r), 29, svcoff); return; } @@ -680,17 +679,17 @@ ST_FUNC void store(int r, SValue *sv) if (svr == (VT_CONST | VT_LVAL | VT_SYM)) { arm64_sym(30, sv->sym, // use x30 for address - arm64_check_offset(0, arm64_type_size(svtt), svcul)); + arm64_check_offset(0, arm64_type_size(svtt), svcoff)); if (IS_FREG(r)) arm64_strv(arm64_type_size(svtt), fltr(r), 30, - arm64_check_offset(1, arm64_type_size(svtt), svcul)); + arm64_check_offset(1, arm64_type_size(svtt), svcoff)); else arm64_strx(arm64_type_size(svtt), intr(r), 30, - arm64_check_offset(1, arm64_type_size(svtt), svcul)); + arm64_check_offset(1, arm64_type_size(svtt), svcoff)); return; } - printf("store(%x, (%x, %x, %lx))\n", r, svtt, sv->r, (long)svcul); + printf("store(%x, (%x, %x, %lx))\n", r, svtt, sv->r, (long)svcoff); assert(0); } diff --git a/arm64-tok.h b/arm64-tok.h index 4e299614..81951598 100644 --- a/arm64-tok.h +++ b/arm64-tok.h @@ -676,7 +676,7 @@ #define ARM64_BL 0x94000000U #define ARM64_BR 0xD61F0000U #define ARM64_BLR 0xD63F0000U -#define ARM64_RET 0xD65F001FU +#define ARM64_RET 0xD65F0000U /* Conditional branch */ #define ARM64_B_COND 0x54000000U diff --git a/tccpe.c b/tccpe.c index a3491aea..5c9f3d5e 100644 --- a/tccpe.c +++ b/tccpe.c @@ -40,9 +40,21 @@ static HMODULE pe_get_process_msvcrt_handle(void) wait_sem(&pe_msvcrt_sem); dll = handle; if (!dll) { - dll = GetModuleHandleA("msvcrt.dll"); - if (dll) + if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_PIN, "msvcrt.dll", &dll)) { handle = dll; + } else { + dll = LoadLibraryA("msvcrt.dll"); + if (dll) { + HMODULE pinned; + /* Keep one process-lifetime handle so later states do not cache + an unloadable msvcrt handle after the first state is deleted. */ + if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_PIN, "msvcrt.dll", &pinned)) { + FreeLibrary(dll); + dll = pinned; + } + handle = dll; + } + } } post_sem(&pe_msvcrt_sem); return dll; diff --git a/win32/build-tcc.bat b/win32/build-tcc.bat index e6011c6f..107508f7 100644 --- a/win32/build-tcc.bat +++ b/win32/build-tcc.bat @@ -224,4 +224,11 @@ exit /B %ERRORLEVEL% .\tcc -B. -m%1 -c ../lib/bt-log.c -o lib/%2bt-log.o .\tcc -B. -m%1 -c ../lib/bt-dll.c -o lib/%2bt-dll.o .\tcc -B. -m%1 -c ../lib/runmain.c -o lib/%2runmain.o +@if "%~2"=="" ( + @rem Keep the repo-root runtime helpers in sync for native -run and tests. + if exist tcc.exe copy>nul /y tcc.exe ..\tcc.exe + if exist libtcc.dll copy>nul /y libtcc.dll ..\libtcc.dll + copy>nul /y lib\libtcc1.a ..\libtcc1.a + for %%f in (bcheck bt-dll bt-exe bt-log runmain) do @copy>nul /y lib\%%f.o ..\%%f.o +) exit /B %ERRORLEVEL%