Compare commits

..

No commits in common. "cb41cbfe717e4c00d7bb70035cda5ee5f0ff9341" and "7e4fc3a0d01173575b3b29f71ae4da87322ba14b" have entirely different histories.

19 changed files with 80 additions and 380 deletions

View File

@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-22.04
timeout-minutes: 2
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: actions/checkout@v4
- name: make & test tcc (x86_64-linux)
run: ./configure && make && make test -k
@ -17,7 +17,7 @@ jobs:
runs-on: macos-13
timeout-minutes: 2
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: actions/checkout@v4
- name: make & test tcc (x86_64-osx)
run: ./configure && make && make test -k
@ -25,7 +25,7 @@ jobs:
runs-on: macos-14
timeout-minutes: 2
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: actions/checkout@v4
- name: make & test tcc (aarch64-osx)
run: ./configure && make && make test -k
@ -33,7 +33,7 @@ jobs:
runs-on: windows-2025
timeout-minutes: 6
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: actions/checkout@v4
- name: make & test tcc (x86_64-win32)
shell: cmd
run: |
@ -44,7 +44,7 @@ jobs:
C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-x86_64-gcc"
echo ::endgroup::
C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: amd64
- name: build with MSVC (x86_64-win32)
@ -61,7 +61,7 @@ jobs:
runs-on: windows-2025
timeout-minutes: 6
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: actions/checkout@v4
- name: make & test tcc (i386-win32)
shell: cmd
run: |
@ -72,7 +72,7 @@ jobs:
C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-i686-gcc"
echo ::endgroup::
C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
- uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: x86
- name: build with MSVC (i386-win32)
@ -89,8 +89,8 @@ jobs:
runs-on: ubuntu-22.04
timeout-minutes: 8
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v3
name: make & test tcc (armv7-linux)
with:
arch: armv7
@ -107,8 +107,8 @@ jobs:
runs-on: ubuntu-22.04
timeout-minutes: 8
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v3
name: make & test tcc (aarch64-linux)
with:
arch: aarch64
@ -125,8 +125,8 @@ jobs:
runs-on: ubuntu-22.04
timeout-minutes: 8
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
- uses: uraimo/run-on-arch-action@d94c13912ea685de38fccc1109385b83fd79427d # v3.0.1
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v3
name: make & test tcc (riscv64-linux)
with:
arch: riscv64

View File

@ -19,7 +19,9 @@ typedef union { long long __ll; long double __ld; } max_align_t;
#undef offsetof
#define offsetof(type, field) __builtin_offsetof(type, field)
#if defined __i386__ || defined __x86_64__
void *alloca(size_t size);
#endif
#endif

View File

@ -347,8 +347,12 @@
__MAYBE_REDIR(void*, calloc, (__SIZE_TYPE__, __SIZE_TYPE__))
__MAYBE_REDIR(void*, memalign, (__SIZE_TYPE__, __SIZE_TYPE__))
__MAYBE_REDIR(void, free, (void*))
#if defined __i386__ || defined __x86_64__
__BOTH(void*, alloca, (__SIZE_TYPE__))
void *alloca(__SIZE_TYPE__);
#else
__BUILTIN(void*, alloca, (__SIZE_TYPE__))
#endif
__BUILTIN(void, abort, (void))
__BOUND(void, longjmp, ())
#if !defined _WIN32

View File

@ -35,12 +35,12 @@ endif
XFLAGS += -I$(TOP)
I386_O = libtcc1.o $(COMMON_O)
X86_64_O = libtcc1.o $(COMMON_O)
ARM_O = libtcc1.o armeabi.o armflush.o $(COMMON_O)
ARM64_O = lib-arm64.o $(COMMON_O)
I386_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O)
X86_64_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O)
ARM_O = libtcc1.o armeabi.o alloca.o armflush.o $(COMMON_O)
ARM64_O = lib-arm64.o alloca.o $(COMMON_O)
RISCV64_O = lib-arm64.o $(COMMON_O)
COMMON_O = stdatomic.o atomic.o builtin.o alloca.o alloca-bt.o
COMMON_O = stdatomic.o atomic.o builtin.o
WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
LIN_O = dsohandle.o
OSX_O =

View File

@ -92,109 +92,5 @@ p3:
ret
#endif
/* ---------------------------------------------- */
#elif defined __arm__
.globl _(__bound_alloca)
_(__bound_alloca):
mov r1, r0
add r0, r0, #1
rsb sp, r0, sp
bic sp, sp, #7
mov r0, sp
push { lr }
bl _(__bound_new_region)
pop { lr }
mov r0, sp
mov pc, lr
/* ---------------------------------------------- */
#elif defined __aarch64__ || defined __arm64__
.globl _(__bound_alloca)
_(__bound_alloca):
#ifdef __TINYC__
.int 0xaa0003e1
.int 0x91004000
.int 0x927cec00
#ifdef _WIN32
.int 0xb4000160
.int 0xd2820002
.int 0xeb02001f
.int 0x540000c3
.int 0xcb2263e3
.int 0xf940007f
.int 0xcb2263ff
.int 0xcb020000
.int 0x17fffffa
.int 0xb4000040
#endif
.int 0xcb2063ff
.int 0x910003e0
.int 0xa9bf7bfd
.reloc ., R_AARCH64_CALL26, _(__bound_new_region)
.int 0x94000000
.int 0xa8c17bfd
.int 0x910003e0
.int 0xd65f03c0
#else
mov x1, x0
add x0, x0, #16 // Round up to 16-byte boundary
and x0, x0, #-16 // Ensure 16-byte alignment
#ifdef _WIN32
cbz x0, p100 // If size is 0, skip to return
// Windows requires page-wise allocation with stack probing
mov x2, #4096 // Page size = 4096 bytes
p101:
cmp x0, x2 // Compare remaining size with page size
b.lo p102 // If less than page, jump to remainder
// Probe first, then allocate
sub x3, sp, x2 // Calculate guard page address (sp - 4096)
ldr xzr, [x3] // Touch guard page FIRST
sub sp, sp, x2 // THEN allocate the page
sub x0, x0, x2 // Decrement remaining size
b p101 // Continue loop
p102:
// Allocate remaining bytes (less than one page)
cbz x0, p100 // If no remaining bytes, skip
sub sp, sp, x0 // Allocate remaining space
#else
// Non-Windows: simple one-time allocation
sub sp, sp, x0 // Allocate space on stack
#endif
p100:
mov x0, sp // Return allocated address
stp x29, x30, [sp, #-16]!
bl _(__bound_new_region)
ldp x29, x30, [sp], #16
mov x0, sp // Return allocated address
ret // Return to caller
#endif
/* ---------------------------------------------- */
#elif defined __riscv
.globl _(__bound_alloca)
_(__bound_alloca):
mv a1, a0
sub sp, sp, a0
addi sp, sp, -16
andi sp, sp, -16
add a0, sp, zero
addi sp,sp,-16
sd s0,0(sp)
sd ra,8(sp)
jal _(__bound_new_region)
ld s0,0(sp)
ld ra,8(sp)
addi sp,sp,16
add a0, sp, zero
ret
/* ---------------------------------------------- */
#endif

View File

@ -70,18 +70,25 @@ p3:
/* ---------------------------------------------- */
#elif defined __arm__
.globl _(alloca)
_(alloca):
.text
.align 2
.global alloca
.type alloca, %function
alloca:
rsb sp, r0, sp
bic sp, sp, #7
mov r0, sp
mov pc, lr
.size alloca, .-alloca
/* ---------------------------------------------- */
#elif defined __aarch64__ || defined __arm64__
.globl _(alloca)
_(alloca):
.text
.align 2
.global alloca
.type alloca, %function
alloca:
#ifdef __TINYC__
.int 0x91003c00
.int 0x927cec00
@ -95,16 +102,16 @@ _(alloca):
.int 0xcb2163ff
.int 0xcb010000
.int 0x17fffffa
.int 0xb4000040
#endif
.int 0xb4000040
.int 0xcb2063ff
.int 0x910003e0
.int 0xd65f03c0
#else
add x0, x0, #15 // Round up to 16-byte boundary
and x0, x0, #-16 // Ensure 16-byte alignment
#ifdef _WIN32
cbz x0, p100 // If size is 0, skip to return
#ifdef _WIN32
// Windows requires page-wise allocation with stack probing
mov x1, #4096 // Page size = 4096 bytes
@ -133,16 +140,6 @@ p100:
mov x0, sp // Return allocated address
ret // Return to caller
#endif
.size alloca, .-alloca
/* ---------------------------------------------- */
#elif defined __riscv
.globl _(alloca)
_(alloca):
sub sp, sp, a0
addi sp, sp, -15
andi sp, sp, -16
add a0, sp, zero
ret
#endif

View File

@ -40,7 +40,7 @@
#elif defined(TCC_TARGET_ARM64)
#include "arm64-gen.c"
#include "arm64-link.c"
#include "arm64-asm.c"
#include "arm-asm.c"
#elif defined(TCC_TARGET_C67)
#include "c67-gen.c"
#include "c67-link.c"

View File

@ -63,9 +63,6 @@ static void asm_emit_opcode(uint32_t opcode);
static void asm_emit_r(int token, uint32_t opcode, const Operand *rd, const Operand *rs1, const Operand *rs2);
static void asm_emit_s(int token, uint32_t opcode, const Operand *rs1, const Operand *rs2, const Operand *imm);
static void asm_emit_u(int token, uint32_t opcode, const Operand *rd, const Operand *rs2);
static void asm_emit_f(int token, uint32_t opcode, const Operand *rd, const Operand *rs1, const Operand *rs2);
static void asm_emit_fb(int token, uint32_t opcode, const Operand *rd, const Operand *rs);
static void asm_emit_fq(int token, uint32_t opcode, const Operand *rd, const Operand *rs1, const Operand *rs2, const Operand *rs3);
ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
static void asm_nullary_opcode(TCCState *s1, int token);
ST_FUNC void asm_opcode(TCCState *s1, int token);
@ -398,15 +395,6 @@ static void asm_unary_opcode(TCCState *s1, int token)
case TOK_ASM_rdinstreth:
asm_emit_opcode(opcode | (0xC82 << 20) | ENCODE_RD(op.reg));
return;
case TOK_ASM_frflags:
asm_emit_opcode(opcode | (0x001 << 20) | ENCODE_RD(op.reg));
return;
case TOK_ASM_frrm:
asm_emit_opcode(opcode | (0x002 << 20) | ENCODE_RD(op.reg));
return;
case TOK_ASM_frcsr:
asm_emit_opcode(opcode | (0x003 << 20) | ENCODE_RD(op.reg));
return;
case TOK_ASM_jr:
/* jalr zero, 0(rs)*/
@ -440,7 +428,6 @@ static void asm_unary_opcode(TCCState *s1, int token)
case TOK_ASM_c_jr:
asm_emit_cr(token, 2 | (8 << 12), &op, &zero);
return;
default:
expect("unary instruction");
}
@ -600,14 +587,6 @@ static void asm_binary_opcode(TCCState* s1, int token)
asm_emit_css(token, 2 | (5 << 13), ops, ops + 1);
return;
/* F/D extension */
case TOK_ASM_fsqrt_d:
asm_emit_fb(token, 0x53 | (11 << 27) | (1 << 25) | (7 << 12), ops, ops + 1);
return;
case TOK_ASM_fsqrt_s:
asm_emit_fb(token, 0x53 | (11 << 27) | (0 << 25) | (7 << 12), ops, ops + 1);
return;
/* pseudoinstructions */
/* rd, sym */
case TOK_ASM_la:
@ -703,31 +682,6 @@ static void asm_binary_opcode(TCCState* s1, int token)
asm_emit_r(token, (0xC << 2) | 3 | (2 << 12), &ops[0], &zero, &ops[1]);
return;
case TOK_ASM_fabs_d:
/* fsgnjx.d rd, rs, rs */
asm_emit_f(token, 0x53 | (4 << 27) | (1 << 25) | (2 << 12), &ops[0], &ops[1], &ops[1]);
return;
case TOK_ASM_fabs_s:
/* fsgnjx.s rd, rs, rs */
asm_emit_f(token, 0x53 | (4 << 27) | (0 << 25) | (2 << 12), &ops[0], &ops[1], &ops[1]);
return;
case TOK_ASM_csrs:
/* csrrs x0, csr, rs */
asm_emit_opcode(0x73 | (2 << 12) | (ops[0].e.v << 20) | ENCODE_RS1(ops[1].reg));
return;
case TOK_ASM_csrc:
/* csrrc x0, csr, rs */
asm_emit_opcode(0x73 | (3 << 12) | (ops[0].e.v << 20) | ENCODE_RS1(ops[1].reg));
return;
case TOK_ASM_fsrm:
/* csrrw rd, frm, rs */
asm_emit_opcode(0x73 | (1 << 12) | (2 << 20) | ENCODE_RD(ops[0].reg) | ENCODE_RS1(ops[1].reg));
return;
case TOK_ASM_fscsr:
/* csrrw rd, fcsr, rs */
asm_emit_opcode(0x73 | (1 << 12) | (3 << 20) | ENCODE_RD(ops[0].reg) | ENCODE_RS1(ops[1].reg));
return;
default:
expect("binary instruction");
}
@ -755,73 +709,6 @@ static void asm_emit_r(int token, uint32_t opcode, const Operand* rd, const Oper
gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg));
}
/* caller: Add rounding mode, fmt, funct5 to opcode */
static void asm_emit_f(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
{
if (rd->type != OP_REG || !REG_IS_FLOAT(rd->reg)) {
tcc_error("'%s': Expected destination operand that is a floating-point register", get_tok_str(token, NULL));
}
if (rs1->type != OP_REG || !REG_IS_FLOAT(rs1->reg)) {
tcc_error("'%s': Expected first source operand that is a floating-point register", get_tok_str(token, NULL));
}
if (rs2->type != OP_REG || !REG_IS_FLOAT(rs2->reg)) {
tcc_error("'%s': Expected second source operand that is a floating-point register", get_tok_str(token, NULL));
}
/* F-type instruction:
31...27 funct5
26...25 fmt
24...20 rs2
19...15 rs1
14...12 rm
11...7 rd
6...0 opcode = OP-FP */
gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg));
}
/* caller: Add rounding mode, fmt, funct5 to opcode */
static void asm_emit_fb(int token, uint32_t opcode, const Operand* rd, const Operand* rs)
{
if (rd->type != OP_REG || !REG_IS_FLOAT(rd->reg)) {
tcc_error("'%s': Expected destination operand that is a floating-point register", get_tok_str(token, NULL));
}
if (rs->type != OP_REG || !REG_IS_FLOAT(rs->reg)) {
tcc_error("'%s': Expected source operand that is a floating-point register", get_tok_str(token, NULL));
}
/* F-type instruction:
31...27 funct5
26...25 fmt
24...20 rs2 = 0
19...15 rs1 = rs
14...12 rm
11...7 rd
6...0 opcode = OP-FP */
gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs->reg) | ENCODE_RS2(0));
}
/* caller: Add rounding mode, fmt to opcode */
static void asm_emit_fq(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2, const Operand* rs3)
{
if (rd->type != OP_REG || !REG_IS_FLOAT(rd->reg)) {
tcc_error("'%s': Expected destination operand that is a floating-point register", get_tok_str(token, NULL));
}
if (rs1->type != OP_REG || !REG_IS_FLOAT(rs1->reg)) {
tcc_error("'%s': Expected first source operand that is a floating-point register", get_tok_str(token, NULL));
}
if (rs2->type != OP_REG || !REG_IS_FLOAT(rs2->reg)) {
tcc_error("'%s': Expected second source operand that is a floating-point register", get_tok_str(token, NULL));
}
if (rs3->type != OP_REG || !REG_IS_FLOAT(rs3->reg)) {
tcc_error("'%s': Expected third source operand that is a floating-point register", get_tok_str(token, NULL));
}
/* F-type instruction:
31...27 rs3
26...25 fmt
24...20 rs2
19...15 rs1
14...12 rm
11...7 rd
6...0 opcode */
gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg) | (REG_VALUE(rs3->reg) << 27));
}
/* caller: Add funct3 into opcode */
static void asm_emit_i(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
{
@ -1202,49 +1089,11 @@ static void asm_ternary_opcode(TCCState *s1, int token)
asm_emit_cs(token, 6 << 13, ops, ops + 1, ops + 2);
return;
/* F/D extension */
case TOK_ASM_fsgnj_d:
asm_emit_f(token, 0x53 | (4 << 27) | (1 << 25) | (0 << 12), ops, ops + 1, ops + 2);
return;
case TOK_ASM_fsgnj_s:
asm_emit_f(token, 0x53 | (4 << 27) | (0 << 25) | (0 << 12), ops, ops + 1, ops + 2);
return;
case TOK_ASM_fmax_d:
asm_emit_f(token, 0x53 | (5 << 27) | (1 << 25) | (1 << 12), ops, ops + 1, ops + 2);
return;
case TOK_ASM_fmax_s:
asm_emit_f(token, 0x53 | (5 << 27) | (0 << 25) | (1 << 12), ops, ops + 1, ops + 2);
return;
case TOK_ASM_fmin_d:
asm_emit_f(token, 0x53 | (5 << 27) | (1 << 25) | (0 << 12), ops, ops + 1, ops + 2);
return;
case TOK_ASM_fmin_s:
asm_emit_f(token, 0x53 | (5 << 27) | (0 << 25) | (0 << 12), ops, ops + 1, ops + 2);
return;
default:
expect("ternary instruction");
}
}
static void asm_quaternary_opcode(TCCState *s1, int token)
{
Operand ops[4];
parse_operands(s1, &ops[0], 4);
switch (token) {
case TOK_ASM_fmadd_d:
asm_emit_fq(token, 0x43 | (1 << 25) | (7 << 12), ops, ops + 1, ops + 2, ops + 3);
return;
case TOK_ASM_fmadd_s:
asm_emit_fq(token, 0x43 | (0 << 25) | (7 << 12), ops, ops + 1, ops + 2, ops + 3);
return;
default:
expect("quaternary instruction");
}
}
static void asm_atomic_opcode(TCCState *s1, int token)
{
Operand ops[3];
@ -1422,8 +1271,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
case TOK_ASM_lui:
case TOK_ASM_auipc:
case TOK_ASM_fsqrt_s:
case TOK_ASM_fsqrt_d:
asm_binary_opcode(s1, token);
return;
@ -1502,19 +1349,8 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
case TOK_ASM_csrrsi:
case TOK_ASM_csrrw:
case TOK_ASM_csrrwi:
/* F/D extension */
case TOK_ASM_fsgnj_d:
case TOK_ASM_fsgnj_s:
case TOK_ASM_fmax_s:
case TOK_ASM_fmax_d:
case TOK_ASM_fmin_s:
case TOK_ASM_fmin_d:
asm_ternary_opcode(s1, token);
return;
case TOK_ASM_fmadd_d:
case TOK_ASM_fmadd_s:
asm_quaternary_opcode(s1, token);
return;
/* Branches */
case TOK_ASM_beq:
@ -1590,9 +1426,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
case TOK_ASM_jr:
case TOK_ASM_call:
case TOK_ASM_tail:
case TOK_ASM_frflags:
case TOK_ASM_frrm:
case TOK_ASM_frcsr:
asm_unary_opcode(s1, token);
return;
@ -1608,12 +1441,6 @@ ST_FUNC void asm_opcode(TCCState *s1, int token)
case TOK_ASM_not:
case TOK_ASM_neg:
case TOK_ASM_negw:
case TOK_ASM_fabs_s:
case TOK_ASM_fabs_d:
case TOK_ASM_csrc:
case TOK_ASM_csrs:
case TOK_ASM_fsrm:
case TOK_ASM_fscsr:
asm_binary_opcode(s1, token);
return;
@ -1729,7 +1556,7 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
if ((sv->type.t & VT_BTYPE) == VT_FLOAT ||
(sv->type.t & VT_BTYPE) == VT_DOUBLE) {
/* floating point register */
reg = TOK_ASM_f0 + REG_VALUE(reg);
reg = TOK_ASM_f0 + reg;
} else {
/* general purpose register */
reg = TOK_ASM_x0 + reg;
@ -1743,7 +1570,7 @@ ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
if ((sv->type.t & VT_BTYPE) == VT_FLOAT ||
(sv->type.t & VT_BTYPE) == VT_DOUBLE) {
/* floating point register */
reg = TOK_ASM_f0 + REG_VALUE(reg);
reg = TOK_ASM_f0 + reg;
} else {
/* general purpose register */
reg = TOK_ASM_x0 + reg;

View File

@ -911,14 +911,18 @@ ST_FUNC void gfunc_epilog(void)
loc = (loc - num_va_regs * 8);
d = v = (-loc + 15) & -16;
EI(0x13, 0, 2, 8, num_va_regs * 8); // addi sp, s0, num_va_regs*8
EI(0x03, 3, 1, 8, -8); // ld ra, -8(s0)
EI(0x03, 3, 8, 8, -16); // ld s0, -16(s0)
EI(0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret
large_ofs_ind = ind;
if (v >= (1 << 11)) {
d = 16;
o(0x37 | (5 << 7) | UPPER(v-16)); //lui t0, upper(v)
EI(0x13, 0, 5, 5, SIGN11(v-16)); // addi t0, t0, lo(v)
ER(0x33, 0, 2, 2, 5, 0); // add sp, sp, t0
}
EI(0x03, 3, 1, 2, d - 8 - num_va_regs * 8); // ld ra, v-8(sp)
EI(0x03, 3, 8, 2, d - 16 - num_va_regs * 8); // ld s0, v-16(sp)
EI(0x13, 0, 2, 2, d); // addi sp, sp, v
EI(0x67, 0, 0, 1, 0); // jalr x0, 0(x1), aka ret
large_ofs_ind = ind;
if (v >= (1 << 11)) {
EI(0x13, 0, 8, 2, d - num_va_regs * 8); // addi s0, sp, d
o(0x37 | (5 << 7) | UPPER(v-16)); //lui t0, upper(v)
EI(0x13, 0, 5, 5, SIGN11(v-16)); // addi t0, t0, lo(v)
@ -1229,10 +1233,6 @@ ST_FUNC void gen_opf(int op)
ER(0x53, op, rd, rs1, rs2, dbl | 0x50); // fcmp.[sd] RD, RS1, RS2 (op == eq/lt/le)
if (invert)
EI(0x13, 4, rd, rd, 1); // xori RD, 1
/* generate VT_CMP output */
vset_VT_CMP(TOK_NE);
vtop->cmp_r = rd | (0 << 8);
break;
case TOK_NE:
invert = 1;

View File

@ -266,19 +266,6 @@
DEF_ASM(remw)
DEF_ASM(remuw)
/* "F"/"D" Extension for Single/Double-Precision Floating Point Arithmetic, V2.2 */
/* enough implemented for musl */
DEF_ASM_WITH_SUFFIX(fsgnj, s)
DEF_ASM_WITH_SUFFIX(fsgnj, d)
DEF_ASM_WITH_SUFFIX(fmadd, s)
DEF_ASM_WITH_SUFFIX(fmadd, d)
DEF_ASM_WITH_SUFFIX(fmax, s)
DEF_ASM_WITH_SUFFIX(fmax, d)
DEF_ASM_WITH_SUFFIX(fmin, s)
DEF_ASM_WITH_SUFFIX(fmin, d)
DEF_ASM_WITH_SUFFIX(fsqrt, s)
DEF_ASM_WITH_SUFFIX(fsqrt, d)
/* "C" Extension for Compressed Instructions, V2.0 */
DEF_ASM_WITH_SUFFIX(c, nop)
/* Loads */

2
tcc.h
View File

@ -385,7 +385,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
#elif defined TCC_TARGET_ARM64
# include "arm64-gen.c"
# include "arm64-link.c"
# include "arm64-asm.c"
# include "arm-asm.c"
#elif defined TCC_TARGET_C67
# define TCC_TARGET_COFF
# include "coff.h"

View File

@ -984,23 +984,6 @@ static void asm_parse_directive(TCCState *s1, int global)
skip('@');
next();
break;
case TOK_ASMDIR_reloc:
{
ExprValue e;
next();
asm_expr(s1, &e);
skip(',');
#if defined(TCC_TARGET_ARM64)
if (strcmp(get_tok_str(tok, NULL), "R_AARCH64_CALL26"))
#endif
tcc_error("unimp: reloc '%s' unknown", get_tok_str(tok, NULL));
next();
skip(',');
greloca(cur_text_section, get_asm_sym(tok, NULL), e.v, R_AARCH64_CALL26, 0);
next();
}
break;
default:
tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
break;

View File

@ -2419,10 +2419,8 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
if (s->sh_type != SHT_NOBITS)
file_offset += s->sh_size;
if (ph) {
ph->p_filesz = file_offset - ph->p_offset;
ph->p_memsz = addr - ph->p_vaddr;
}
ph->p_filesz = file_offset - ph->p_offset;
ph->p_memsz = addr - ph->p_vaddr;
}
/* Fill other headers */

View File

@ -1701,8 +1701,10 @@ ST_FUNC void gbound_args(int nb_args)
gfunc_call(1);
func_bound_add_epilog = 1;
}
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
if (v == TOK_alloca)
func_bound_add_epilog = 1;
#endif
#if TARGETOS_NetBSD
if (v == TOK_longjmp) /* undo rename to __longjmp14 */
sv->sym->asm_label = TOK___bound_longjmp;
@ -8742,11 +8744,7 @@ static int decl(int l)
while (1) { /* iterate thru each declaration */
type = btype;
ad = adbase;
if (l == VT_CMP) {
type_decl(&type, &ad, &v, TYPE_DIRECT | TYPE_PARAM);
} else {
type_decl(&type, &ad, &v, TYPE_DIRECT);
}
type_decl(&type, &ad, &v, TYPE_DIRECT);
/*ptype("decl", &type, v);*/
if ((type.t & VT_BTYPE) == VT_FUNC) {

View File

@ -23,6 +23,8 @@
DEF(TOK_CONST1, "const")
DEF(TOK_CONST2, "__const") /* gcc keyword */
DEF(TOK_CONST3, "__const__") /* gcc keyword */
DEF(TOK_PURE1, "pure")
DEF(TOK_PURE2, "__pure__")
DEF(TOK_VOLATILE1, "volatile")
DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
@ -145,8 +147,6 @@
DEF(TOK_ALWAYS_INLINE1, "always_inline")
DEF(TOK_ALWAYS_INLINE2, "__always_inline__")
DEF(TOK_NOINLINE, "__noinline__")
DEF(TOK_PURE1, "pure")
DEF(TOK_PURE2, "__pure__")
DEF(TOK_MODE, "__mode__")
DEF(TOK_MODE_QI, "__QI__")
@ -301,7 +301,9 @@
DEF(TOK___fixxfdi, "__fixxfdi")
#endif
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
DEF(TOK_alloca, "alloca")
#endif
#if defined TCC_TARGET_PE
DEF(TOK___chkstk, "__chkstk")
@ -413,7 +415,6 @@
DEF_ASMDIR(long)
DEF_ASMDIR(int)
DEF_ASMDIR(symver)
DEF_ASMDIR(reloc)
DEF_ASMDIR(section) /* must be last directive */
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64

View File

@ -169,6 +169,14 @@ int test13(void)
return strlen(tab);
}
#if defined __i386__ || defined __x86_64__
#define allocf(x)
#else
#undef alloca
#define alloca(x) malloc(x)
#define allocf(x) free(x)
#endif
int test14(void)
{
char *p = alloca(TAB_SIZE);
@ -176,6 +184,7 @@ int test14(void)
memset(p, 'a', TAB_SIZE);
p[TAB_SIZE-1] = 0;
ret = strlen(p);
allocf(p);
return ret;
}
@ -187,6 +196,7 @@ int test15(void)
memset(p, 'a', TAB_SIZE);
p[TAB_SIZE-1] = 0;
ret = strlen(p);
allocf(p);
return ret;
}
@ -201,6 +211,8 @@ int test16()
/* Test alloca embedded in a larger expression */
printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)+1),demo) );
allocf(p);
allocf(q);
return 0;
}
@ -216,6 +228,8 @@ int test17()
/* Test alloca embedded in a larger expression */
printf("alloca : %s : %s\n", p, strcpy(q=alloca(strlen(demo)),demo) );
allocf(p);
allocf(q);
return 0;
}

View File

@ -2941,12 +2941,14 @@ void old_style_function_test(void)
void alloca_test()
{
#if defined __i386__ || defined __x86_64__ || defined __arm__
char *p = alloca(16);
strcpy(p,"123456789012345");
printf("alloca: p is %s\n", p);
char *demo = "This is only a test.\n";
/* Test alloca embedded in a larger expression */
printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
#endif
}
void *bounds_checking_is_enabled()
@ -4206,6 +4208,7 @@ double get100 () { return 100.0; }
void callsave_test(void)
{
#if defined __i386__ || defined __x86_64__ || defined __arm__
int i, s; double *d; double t;
s = sizeof (double);
printf ("callsavetest: %d\n", s);
@ -4218,6 +4221,7 @@ void callsave_test(void)
generates a segfault. */
i = d[0] > get100 ();
printf ("%d\n", i);
#endif
}

View File

@ -1173,8 +1173,7 @@ extern "C" {
#define WM_XBUTTONDOWN 0x020B
#define WM_XBUTTONUP 0x020C
#define WM_XBUTTONDBLCLK 0x020D
#define WM_MOUSEHWHEEL 0x020E
#define WM_MOUSELAST 0x020E
#define WM_MOUSELAST 0x020D
#define WHEEL_DELTA 120
#define GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))

View File

@ -509,12 +509,7 @@ ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
DEF_ASM_OP2(cvtss2si, 0xf30f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_REG32 )
ALT(DEF_ASM_OP2(cvtss2si, 0xf30f2d, 0, OPC_MODRM | OPC_48, OPT_EA | OPT_SSE, OPT_REG64 ))
DEF_ASM_OP2(cvtsd2si, 0xf20f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_REG32 )
ALT(DEF_ASM_OP2(cvtsd2si, 0xf20f2d, 0, OPC_MODRM | OPC_48, OPT_EA | OPT_SSE, OPT_REG64 ))
DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
DEF_ASM_OP2(andps, 0x0f54, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
@ -528,13 +523,8 @@ ALT(DEF_ASM_OP2(cvtsd2si, 0xf20f2d, 0, OPC_MODRM | OPC_48, OPT_EA | OPT_SSE, OPT
DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(sqrtss, 0xf30f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
/* sse2 */
DEF_ASM_OP2(andpd, 0x660f54, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE)
DEF_ASM_OP2(sqrtsd, 0xf20f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE)
/* movnti should only accept REG32 and REG64, we accept more */
DEF_ASM_OP2(movnti, 0x0fc3, 0, OPC_MODRM, OPT_REG, OPT_EA)
DEF_ASM_OP2(movntil, 0x0fc3, 0, OPC_MODRM, OPT_REG32, OPT_EA)