mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-19 11:24:19 +08:00
Fix Windows ARM64 runtime regressions
This commit is contained in:
parent
4f4b3dda6b
commit
cf4441c415
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@ -100,7 +100,17 @@ jobs:
|
||||
cd win32
|
||||
call build-tcc.bat -t arm64 -c clang
|
||||
echo ::endgroup::
|
||||
.\tcc -v
|
||||
.\tcc -B. -v
|
||||
.\tcc -B. ..\win32\test_arm64.c -o test_arm64.exe && .\test_arm64.exe
|
||||
.\tcc -B. -run ..\examples\ex1.c
|
||||
> test_rstdin.txt echo arm64 stdin
|
||||
.\tcc -B. -rstdin test_rstdin.txt -run ..\win32\test_rstdin.c > test_rstdin.out
|
||||
type test_rstdin.out
|
||||
fc /n test_rstdin.out test_rstdin.txt
|
||||
.\tcc -B. ..\tests\tests2\49_bracket_evaluation.c -o test49.exe && .\test49.exe > test49.out
|
||||
fc /n test49.out ..\tests\tests2\49_bracket_evaluation.expect
|
||||
.\tcc -B. ..\tests\tests2\133_old_func.c -o test133.exe && .\test133.exe > test133.out
|
||||
fc /n test133.out ..\tests\tests2\133_old_func.expect
|
||||
|
||||
test-armv7-linux:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
35
arm64-asm.c
35
arm64-asm.c
@ -3,7 +3,7 @@
|
||||
* ARM64 (AArch64) assembler for TCC
|
||||
*
|
||||
* Based on ARM64 Architecture Reference Manual
|
||||
* Supports AArch64 instruction set for inline assembly
|
||||
* Supports AArch64 assembler parsing plus basic inline asm strings
|
||||
*/
|
||||
|
||||
#ifdef TARGET_DEFS_ONLY
|
||||
@ -1169,29 +1169,42 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate code for inline asm - ARM64 inline asm with constraints not yet fully implemented */
|
||||
static int asm_has_clobbers(const uint8_t *clobber_regs)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < NB_ASM_REGS; ++i)
|
||||
if (clobber_regs[i])
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Basic inline asm strings are assembled directly by tccasm.c.
|
||||
Operand allocation and clobber handling are still unsupported here. */
|
||||
ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
||||
int nb_outputs, int is_output,
|
||||
uint8_t *clobber_regs,
|
||||
int out_reg)
|
||||
{
|
||||
/* For now, just handle clobber registers by marking them as volatile */
|
||||
/* TODO: Implement full ARM64 inline asm support with register allocation */
|
||||
if (nb_operands > 0 || out_reg > 0) {
|
||||
tcc_error("ARM64 inline asm with operands is not implemented");
|
||||
}
|
||||
gen_nop();
|
||||
(void)operands;
|
||||
(void)nb_outputs;
|
||||
(void)is_output;
|
||||
|
||||
if (nb_operands > 0 || asm_has_clobbers(clobber_regs) || out_reg >= 0)
|
||||
tcc_error("ARM64 extended inline asm is not implemented");
|
||||
}
|
||||
|
||||
/* Compute constraints - ARM64 not yet fully implemented */
|
||||
ST_FUNC void asm_compute_constraints(ASMOperand *operands,
|
||||
int nb_operands, int nb_outputs,
|
||||
const uint8_t *clobber_regs,
|
||||
int *pout_reg)
|
||||
{
|
||||
/* TODO: Implement ARM64 constraint computation */
|
||||
(void)operands;
|
||||
(void)nb_outputs;
|
||||
|
||||
if (pout_reg)
|
||||
*pout_reg = 0;
|
||||
*pout_reg = -1;
|
||||
if (nb_operands > 0 || asm_has_clobbers(clobber_regs))
|
||||
tcc_error("ARM64 extended inline asm is not implemented");
|
||||
}
|
||||
|
||||
/* Handle clobber list */
|
||||
|
||||
19
arm64-gen.c
19
arm64-gen.c
@ -874,12 +874,13 @@ static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned l
|
||||
size = type_size(type[i], &align);
|
||||
|
||||
#if defined(TCC_TARGET_MACHO)
|
||||
if (variadic && i == variadic) {
|
||||
if (variadic > 0 && i == variadic) {
|
||||
nx = 8;
|
||||
nv = 8;
|
||||
}
|
||||
#elif defined(TCC_TARGET_PE)
|
||||
if (variadic && i >= variadic && (hfa || is_float(type[i]->t))) {
|
||||
if ((variadic < 0 || (variadic > 0 && i >= variadic))
|
||||
&& (hfa || is_float(type[i]->t))) {
|
||||
hfa = 0;
|
||||
if (is_float(type[i]->t)) {
|
||||
win_vararg_float = 1;
|
||||
@ -992,6 +993,8 @@ static unsigned long arm64_pcs_aux(int variadic, int n, CType **type, unsigned l
|
||||
return ns - 32;
|
||||
}
|
||||
|
||||
#define ARM64_PCS_ALL_VARARGS (-1)
|
||||
|
||||
static unsigned long arm64_pcs(int variadic, int n, CType **type, unsigned long *a)
|
||||
{
|
||||
unsigned long stack;
|
||||
@ -1074,6 +1077,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
||||
unsigned long *a, *a1;
|
||||
unsigned long stack;
|
||||
int i;
|
||||
int pcs_variadic = 0;
|
||||
int func_type = vtop[-nb_args].type.ref->f.func_type;
|
||||
int variadic = (func_type == FUNC_ELLIPSIS);
|
||||
int old_style = (func_type == FUNC_OLD);
|
||||
@ -1098,7 +1102,11 @@ ST_FUNC void gfunc_call(int nb_args)
|
||||
for (i = 0; i < nb_args; i++)
|
||||
t[nb_args - i] = &vtop[-i].type;
|
||||
|
||||
stack = arm64_pcs((variadic || old_style) ? var_nb_arg : 0, nb_args, t, a);
|
||||
if (variadic)
|
||||
pcs_variadic = var_nb_arg;
|
||||
else if (old_style)
|
||||
pcs_variadic = ARM64_PCS_ALL_VARARGS;
|
||||
stack = arm64_pcs(pcs_variadic, nb_args, t, a);
|
||||
|
||||
// Allocate space for structs replaced by pointer:
|
||||
for (i = nb_args; i; i--)
|
||||
@ -1263,6 +1271,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
||||
static unsigned long arm64_func_va_list_stack;
|
||||
static int arm64_func_va_list_gr_offs;
|
||||
static int arm64_func_va_list_vr_offs;
|
||||
static unsigned arm64_func_start_offset;
|
||||
static int arm64_func_sub_sp_offset;
|
||||
|
||||
#define ARM64_FUNC_STACK_SETUP_SLOTS 6
|
||||
@ -1341,6 +1350,7 @@ ST_FUNC void gfunc_prolog(Sym *func_sym)
|
||||
last_int = last_int > 4 ? 4 : last_int;
|
||||
last_float = last_float > 4 ? 4 : last_float;
|
||||
|
||||
arm64_func_start_offset = ind;
|
||||
o(0xa9b27bfd); // stp x29,x30,[sp,#-224]!
|
||||
for (i = 0; i < last_float; i++)
|
||||
// stp q0,q1,[sp,#16], stp q2,q3,[sp,#48]
|
||||
@ -1664,8 +1674,7 @@ ST_FUNC void gfunc_epilog(void)
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
{
|
||||
unsigned start = arm64_func_sub_sp_offset - 8;
|
||||
pe_add_unwind_data(start, ind, -loc);
|
||||
pe_add_unwind_data(arm64_func_start_offset, ind, -loc);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
9
tcc.c
9
tcc.c
@ -400,6 +400,11 @@ static int tcc_run_via_temp_exe(TCCState *s, int argc, char **argv)
|
||||
DeleteFileA(tmppath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tcc_run_requires_inprocess(const TCCState *s)
|
||||
{
|
||||
return (s->dflag & 16) || s->run_stdin != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@ -513,9 +518,7 @@ redo:
|
||||
if (s->output_type == TCC_OUTPUT_MEMORY) {
|
||||
#ifdef TCC_IS_NATIVE
|
||||
#if defined(_WIN32) && defined(__aarch64__)
|
||||
if (s->dflag & 16)
|
||||
ret = tcc_run(s, argc, argv);
|
||||
else if (first_file && 0 == strcmp(tcc_basename(first_file), "tcc.c"))
|
||||
if (tcc_run_requires_inprocess(s))
|
||||
ret = tcc_run(s, argc, argv);
|
||||
else
|
||||
ret = tcc_run_via_temp_exe(s, argc, argv);
|
||||
|
||||
@ -179,7 +179,7 @@ if exist libtcc.dll .\tcc -impdef libtcc.dll -o libtcc\libtcc.def
|
||||
@if errorlevel 1 goto :the_end
|
||||
|
||||
:lib
|
||||
@rem ARM64 now supported with implemented assembler
|
||||
@rem ARM64 assembler files and basic inline asm strings are supported here.
|
||||
call :make_lib %T% || goto :the_end
|
||||
@if exist %PX%-tcc.exe call :make_lib %TX% %PX%- || goto :the_end
|
||||
|
||||
|
||||
11
win32/test_rstdin.c
Normal file
11
win32/test_rstdin.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (!fgets(buf, sizeof buf, stdin))
|
||||
return 1;
|
||||
printf("%s", buf);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user