diff --git a/Makefile b/Makefile index 83d602ad..1c05e8a0 100644 --- a/Makefile +++ b/Makefile @@ -78,6 +78,7 @@ NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64 +NATIVE_DEFINES_$(CONFIG_riscv64) += -DTCC_TARGET_RISCV64 NATIVE_DEFINES += $(NATIVE_DEFINES_yes) ifeq ($(INCLUDED),no) @@ -92,10 +93,12 @@ all: $(PROGS) $(TCCLIBS) $(TCCDOCS) # cross compiler targets to build TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67 +TCC_X += riscv64 # TCC_X += arm-fpa arm-fpa-ld arm-vfp arm-eabi # cross libtcc1.a targets to build LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince +LIBTCC1_X = riscv64 PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF)) LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a) @@ -133,6 +136,7 @@ DEF-arm-vfp = -DTCC_TARGET_ARM -DTCC_ARM_VFP DEF-arm-eabi = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI DEF-arm-eabihf = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT DEF-arm = $(DEF-arm-eabihf) +DEF-riscv64 = -DTCC_TARGET_RISCV64 DEF-$(NATIVE_TARGET) = $(NATIVE_DEFINES) DEFINES += $(DEF-$T) $(DEF-all) @@ -172,6 +176,7 @@ arm-eabi_FILES = $(arm_FILES) arm-eabihf_FILES = $(arm_FILES) arm64_FILES = $(CORE_FILES) arm64-gen.c arm64-link.c c67_FILES = $(CORE_FILES) c67-gen.c c67-link.c tcccoff.c +riscv64_FILES = $(CORE_FILES) riscv64-gen.c riscv64-link.c # libtcc sources LIBTCC_SRC = $(filter-out tcc.c tcctools.c,$(filter %.c,$($T_FILES))) diff --git a/configure b/configure index 4a404054..1458ae8f 100755 --- a/configure +++ b/configure @@ -232,6 +232,9 @@ case "$cpu" in s390) cpu="s390" ;; + riscv64) + cpu="riscv64" + ;; *) echo "Unsupported CPU" exit 1 diff --git a/conftest.c b/conftest.c index c7bc7831..14babf04 100644 --- a/conftest.c +++ b/conftest.c @@ -13,6 +13,8 @@ # define TRIPLET_ARCH "arm" #elif defined(__aarch64__) # define TRIPLET_ARCH "aarch64" +#elif defined(__riscv) && defined(__LP64__) +# define TRIPLET_ARCH "riscv64" #else # define TRIPLET_ARCH "unknown" #endif diff --git a/elf.h b/elf.h index 9fed6eb7..a78db186 100644 --- a/elf.h +++ b/elf.h @@ -262,7 +262,8 @@ typedef struct #define EM_AARCH64 183 /* ARM AARCH64 */ #define EM_TILEPRO 188 /* Tilera TILEPro */ #define EM_TILEGX 191 /* Tilera TILE-Gx */ -#define EM_NUM 192 +#define EM_RISCV 243 /* RISC-V */ +#define EM_NUM 253 /* If it is necessary to assign new unofficial EM_* values, please pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the @@ -381,7 +382,7 @@ typedef struct #define SHF_MASKPROC 0xf0000000 /* Processor-specific */ #define SHF_ORDERED (1 << 30) /* Special ordering requirement (Solaris). */ -#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless +#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless referenced or allocated (Solaris).*/ /* Section group handling. */ @@ -3233,5 +3234,71 @@ typedef Elf32_Addr Elf32_Conflict; #define R_TILEGX_NUM 130 +/* RISC-V ELF Flags */ +#define EF_RISCV_RVC 0x0001 +#define EF_RISCV_FLOAT_ABI 0x0006 +#define EF_RISCV_FLOAT_ABI_SOFT 0x0000 +#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002 +#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004 +#define EF_RISCV_FLOAT_ABI_QUAD 0x0006 + +/* RISC-V relocations. */ +#define R_RISCV_NONE 0 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 +#define R_RISCV_BRANCH 16 +#define R_RISCV_JAL 17 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 +#define R_RISCV_GOT_HI20 20 +#define R_RISCV_TLS_GOT_HI20 21 +#define R_RISCV_TLS_GD_HI20 22 +#define R_RISCV_PCREL_HI20 23 +#define R_RISCV_PCREL_LO12_I 24 +#define R_RISCV_PCREL_LO12_S 25 +#define R_RISCV_HI20 26 +#define R_RISCV_LO12_I 27 +#define R_RISCV_LO12_S 28 +#define R_RISCV_TPREL_HI20 29 +#define R_RISCV_TPREL_LO12_I 30 +#define R_RISCV_TPREL_LO12_S 31 +#define R_RISCV_TPREL_ADD 32 +#define R_RISCV_ADD8 33 +#define R_RISCV_ADD16 34 +#define R_RISCV_ADD32 35 +#define R_RISCV_ADD64 36 +#define R_RISCV_SUB8 37 +#define R_RISCV_SUB16 38 +#define R_RISCV_SUB32 39 +#define R_RISCV_SUB64 40 +#define R_RISCV_GNU_VTINHERIT 41 +#define R_RISCV_GNU_VTENTRY 42 +#define R_RISCV_ALIGN 43 +#define R_RISCV_RVC_BRANCH 44 +#define R_RISCV_RVC_JUMP 45 +#define R_RISCV_RVC_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 +#define R_RISCV_32_PCREL 57 + +#define R_RISCV_NUM 58 + #endif /* elf.h */ diff --git a/lib/Makefile b/lib/Makefile index bb758e6f..50ed4e24 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -43,6 +43,7 @@ I386_O = libtcc1.o alloca86.o alloca86-bt.o X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o ARM64_O = lib-arm64.o +RISCV64_O = WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o OBJ-i386 = $(I386_O) $(BCHECK_O) $(DSO_O) @@ -58,6 +59,7 @@ OBJ-arm-vfp = $(ARM_O) $(DSO_O) OBJ-arm-eabi = $(ARM_O) $(DSO_O) OBJ-arm-eabihf = $(ARM_O) $(DSO_O) OBJ-arm-wince = $(ARM_O) $(WIN_O) +OBJ-riscv64 = $(RISCV64_O) $(DSO_O) $(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T)) $(XAR) rcs $@ $^ diff --git a/libtcc.c b/libtcc.c index a75c4e49..730a4c4c 100644 --- a/libtcc.c +++ b/libtcc.c @@ -45,25 +45,26 @@ static int nb_states; #include "i386-gen.c" #include "i386-link.c" #include "i386-asm.c" -#endif -#ifdef TCC_TARGET_ARM +#elif defined(TCC_TARGET_ARM) #include "arm-gen.c" #include "arm-link.c" #include "arm-asm.c" -#endif -#ifdef TCC_TARGET_ARM64 +#elif defined(TCC_TARGET_ARM64) #include "arm64-gen.c" #include "arm64-link.c" -#endif -#ifdef TCC_TARGET_C67 +#elif defined(TCC_TARGET_C67) #include "c67-gen.c" #include "c67-link.c" #include "tcccoff.c" -#endif -#ifdef TCC_TARGET_X86_64 +#elif defined(TCC_TARGET_X86_64) #include "x86_64-gen.c" #include "x86_64-link.c" #include "i386-asm.c" +#elif defined(TCC_TARGET_RISCV64) +#include "riscv64-gen.c" +#include "riscv64-link.c" +#else +#error unknown target #endif #ifdef CONFIG_TCC_ASM #include "tccasm.c" diff --git a/riscv64-gen.c b/riscv64-gen.c new file mode 100644 index 00000000..5df43885 --- /dev/null +++ b/riscv64-gen.c @@ -0,0 +1,193 @@ +#ifdef TARGET_DEFS_ONLY + +// Number of registers available to allocator: +#define NB_REGS 16 // x10-x17 aka a0-a7, f10-f17 aka fa0-fa7 + +#define TREG_R(x) (x) // x = 0..7 +#define TREG_F(x) (x + 10) // x = 0..7 + +// Register classes sorted from more general to more precise: +#define RC_INT (1 << 0) +#define RC_FLOAT (1 << 1) +#define RC_R(x) (1 << (2 + (x))) // x = 0..7 +#define RC_F(x) (1 << (10 + (x))) // x = 0..7 + +#define RC_IRET (RC_R(0)) // int return register class +#define RC_FRET (RC_F(0)) // float return register class + +#define REG_IRET (TREG_R(0)) // int return register number +#define REG_FRET (TREG_F(0)) // float return register number + +#define PTR_SIZE 8 + +#define LDOUBLE_SIZE 16 +#define LDOUBLE_ALIGN 16 + +#define MAX_ALIGN 16 + +#define CHAR_IS_UNSIGNED + +#else +#include "tcc.h" + +ST_DATA const int reg_classes[NB_REGS] = { + RC_INT | RC_R(0), + RC_INT | RC_R(1), + RC_INT | RC_R(2), + RC_INT | RC_R(3), + RC_INT | RC_R(4), + RC_INT | RC_R(5), + RC_INT | RC_R(6), + RC_INT | RC_R(7), + RC_FLOAT | RC_F(0), + RC_FLOAT | RC_F(1), + RC_FLOAT | RC_F(2), + RC_FLOAT | RC_F(3), + RC_FLOAT | RC_F(4), + RC_FLOAT | RC_F(5), + RC_FLOAT | RC_F(6), + RC_FLOAT | RC_F(7) +}; + +// Patch all branches in list pointed to by t to branch to a: +ST_FUNC void gsym_addr(int t_, int a_) +{ + uint32_t t = t_; + uint32_t a = a_; + tcc_error("implement me"); + while (t) { + unsigned char *ptr = cur_text_section->data + t; + uint32_t next = read32le(ptr); + if (a - t + 0x8000000 >= 0x10000000) + tcc_error("branch out of range"); + write32le(ptr, (a - t == 4 ? 0xd503201f : // nop + 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b + t = next; + } +} + +ST_FUNC void load(int r, SValue *sv) +{ + tcc_error("implement me"); +} + +ST_FUNC void store(int r, SValue *sv) +{ + tcc_error("implement me"); +} + +ST_FUNC void gfunc_call(int nb_args) +{ + tcc_error("implement me"); +} +ST_FUNC void gfunc_prolog(CType *func_type) +{ + tcc_error("implement me"); +} +ST_FUNC void gen_va_start(void) +{ + tcc_error("implement me"); +} +ST_FUNC void gen_va_arg(CType *t) +{ + tcc_error("implement me"); +} +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, + int *align, int *regsize) +{ + tcc_error("implement me"); +} +ST_FUNC void gfunc_return(CType *func_type) +{ + tcc_error("implement me"); +} +ST_FUNC void gfunc_epilog(void) +{ + tcc_error("implement me"); +} +ST_FUNC void gen_fill_nops(int bytes) +{ + tcc_error("implement me"); + if ((bytes & 3)) + tcc_error("alignment of code section not multiple of 4"); +} + +// Generate forward branch to label: +ST_FUNC int gjmp(int t) +{ + tcc_error("implement me"); +} + +// Generate branch to known address: +ST_FUNC void gjmp_addr(int a) +{ + tcc_error("implement me"); +} + +ST_FUNC int gjmp_cond(int op, int t) +{ + tcc_error("implement me"); +} + +ST_FUNC int gjmp_append(int n, int t) +{ + tcc_error("implement me"); +} + +ST_FUNC int gtst(int inv, int t) +{ + tcc_error("implement me"); +} +ST_FUNC void gen_opi(int op) +{ + tcc_error("implement me"); +} + +ST_FUNC void gen_opl(int op) +{ + tcc_error("implement me"); +} + +ST_FUNC void gen_opf(int op) +{ + tcc_error("implement me"); +} +ST_FUNC void gen_cvt_sxtw(void) +{ + tcc_error("implement me"); +} + +ST_FUNC void gen_cvt_itof(int t) +{ + tcc_error("implement me"); +} + +ST_FUNC void gen_cvt_ftoi(int t) +{ + tcc_error("implement me"); +} + +ST_FUNC void gen_cvt_ftof(int t) +{ + tcc_error("implement me"); +} + +ST_FUNC void ggoto(void) +{ + tcc_error("implement me"); +} +ST_FUNC void gen_vla_sp_save(int addr) +{ + tcc_error("implement me"); +} + +ST_FUNC void gen_vla_sp_restore(int addr) +{ + tcc_error("implement me"); +} + +ST_FUNC void gen_vla_alloc(CType *type, int align) +{ + tcc_error("implement me"); +} +#endif diff --git a/riscv64-link.c b/riscv64-link.c new file mode 100644 index 00000000..9e50c5ad --- /dev/null +++ b/riscv64-link.c @@ -0,0 +1,122 @@ +#ifdef TARGET_DEFS_ONLY + +#define EM_TCC_TARGET EM_RISCV + +#define R_DATA_32 R_RISCV_32 +#define R_DATA_PTR R_RISCV_64 +#define R_JMP_SLOT R_RISCV_JUMP_SLOT +#define R_GLOB_DAT R_RISCV_64 +#define R_COPY R_RISCV_COPY +#define R_RELATIVE R_RISCV_RELATIVE + +#define R_NUM R_RISCV_NUM + +#define ELF_START_ADDR 0x00010000 +#define ELF_PAGE_SIZE 0x1000 + +#define PCRELATIVE_DLLPLT 1 +#define RELOCATE_DLLPLT 1 + +#else /* !TARGET_DEFS_ONLY */ + +#include "tcc.h" + +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown + relocations, returns -1. */ +int code_reloc (int reloc_type) +{ + switch (reloc_type) { + } + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +/* Returns an enumerator to describe whether and when the relocation needs a + GOT and/or PLT entry to be created. See tcc.h for a description of the + different values. */ +int gotplt_entry_type (int reloc_type) +{ + switch (reloc_type) { + } + + tcc_error ("Unknown relocation type: %d", reloc_type); + return -1; +} + +ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) +{ + Section *plt = s1->plt; + uint8_t *p; + unsigned plt_offset; + + if (s1->output_type == TCC_OUTPUT_DLL) + tcc_error("DLLs unimplemented!"); + + if (plt->data_offset == 0) + section_ptr_add(plt, 32); + plt_offset = plt->data_offset; + + p = section_ptr_add(plt, 16); + write64le(p, got_offset); + return plt_offset; +} + +/* relocate the PLT: compute addresses and offsets in the PLT now that final + address for PLT and GOT are known (see fill_program_header) */ +ST_FUNC void relocate_plt(TCCState *s1) +{ + uint8_t *p, *p_end; + + if (!s1->plt) + return; + + p = s1->plt->data; + p_end = p + s1->plt->data_offset; + + if (p < p_end) { + uint64_t plt = s1->plt->sh_addr; + uint64_t got = s1->got->sh_addr; + uint64_t off = (got >> 12) - (plt >> 12); + if ((off + ((uint32_t)1 << 20)) >> 21) + tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt); + write32le(p, 0x0); + write32le(p + 4, 0x0); + write32le(p + 8, 0x0); + write32le(p + 12, 0x0); + write32le(p + 16, 0x0); + write32le(p + 20, 0x0); + write32le(p + 24, 0x0); + write32le(p + 28, 0x0); + p += 32; + while (p < p_end) { + uint64_t pc = plt + (p - s1->plt->data); + uint64_t addr = got + read64le(p); + uint64_t off = (addr >> 12) - (pc >> 12); + if ((off + ((uint32_t)1 << 20)) >> 21) + tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc); + write32le(p, 0x0); + write32le(p + 4, 0x0); + write32le(p + 8, 0x0); + write32le(p + 12, 0x0); + p += 16; + } + } +} + +void relocate_init(Section *sr) {} + +void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) +{ + int sym_index = ELFW(R_SYM)(rel->r_info); +#ifdef DEBUG_RELOC + ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; +#endif + + switch(type) { + default: + fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n", + type, (unsigned)addr, ptr, (unsigned)val); + return; + } +} +#endif diff --git a/tcc.h b/tcc.h index 640f2edf..fe3f6420 100644 --- a/tcc.h +++ b/tcc.h @@ -139,11 +139,12 @@ extern long double strtold (const char *__nptr, char **__endptr); /* #define TCC_TARGET_ARM *//* ARMv4 code generator */ /* #define TCC_TARGET_ARM64 *//* ARMv8 code generator */ /* #define TCC_TARGET_C67 *//* TMS320C67xx code generator */ +/* #define TCC_TARGET_RISCV64 *//* risc-v code generator */ /* default target is I386 */ #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \ - !defined(TCC_TARGET_X86_64) + !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_RISCV64) # if defined __x86_64__ # define TCC_TARGET_X86_64 # elif defined __arm__ @@ -170,6 +171,8 @@ extern long double strtold (const char *__nptr, char **__endptr); # define TCC_IS_NATIVE # elif defined __aarch64__ && defined TCC_TARGET_ARM64 # define TCC_IS_NATIVE +# elif defined __riscv && defined __LP64__ && defined TCC_TARGET_RISCV64 +# define TCC_IS_NATIVE # endif #endif @@ -330,25 +333,26 @@ extern long double strtold (const char *__nptr, char **__endptr); #ifdef TCC_TARGET_I386 # include "i386-gen.c" # include "i386-link.c" -#endif -#ifdef TCC_TARGET_X86_64 +#elif defined TCC_TARGET_X86_64 # include "x86_64-gen.c" # include "x86_64-link.c" -#endif -#ifdef TCC_TARGET_ARM +#elif defined TCC_TARGET_ARM # include "arm-gen.c" # include "arm-link.c" # include "arm-asm.c" -#endif -#ifdef TCC_TARGET_ARM64 +#elif defined TCC_TARGET_ARM64 # include "arm64-gen.c" # include "arm64-link.c" -#endif -#ifdef TCC_TARGET_C67 +#elif defined TCC_TARGET_C67 # define TCC_TARGET_COFF # include "coff.h" # include "c67-gen.c" # include "c67-link.c" +#elif defined(TCC_TARGET_RISCV64) +# include "riscv64-gen.c" +# include "riscv64-link.c" +#else +#error unknown target #endif #undef TARGET_DEFS_ONLY @@ -1594,6 +1598,14 @@ ST_FUNC void gen_va_arg(CType *t); ST_FUNC void gen_clear_cache(void); #endif +/* ------------ riscv64-gen.c ------------ */ +#ifdef TCC_TARGET_RISCV64 +ST_FUNC void gen_cvt_sxtw(void); +ST_FUNC void gen_opl(int op); +ST_FUNC void gfunc_return(CType *func_type); +ST_FUNC void gen_va_start(void); +ST_FUNC void gen_va_arg(CType *t); +#endif /* ------------ c67-gen.c ------------ */ #ifdef TCC_TARGET_C67 #endif diff --git a/tccgen.c b/tccgen.c index b7e0fcfc..5173275e 100644 --- a/tccgen.c +++ b/tccgen.c @@ -1548,12 +1548,14 @@ ST_FUNC int gv(int rc) r = vtop->r & VT_VALMASK; rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT; #ifndef TCC_TARGET_ARM64 +#ifndef TCC_TARGET_RISCV64 /* XXX: remove the whole LRET/QRET class */ if (rc == RC_IRET) rc2 = RC_LRET; #ifdef TCC_TARGET_X86_64 else if (rc == RC_FRET) rc2 = RC_QRET; #endif +#endif #endif /* need to reload if: - constant @@ -2552,7 +2554,7 @@ redo: /* generic itof for unsigned long long case */ static void gen_cvt_itof1(int t) { -#ifdef TCC_TARGET_ARM64 +#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 gen_cvt_itof(t); #else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == @@ -2580,7 +2582,7 @@ static void gen_cvt_itof1(int t) /* generic ftoi for unsigned long long case */ static void gen_cvt_ftoi1(int t) { -#ifdef TCC_TARGET_ARM64 +#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 gen_cvt_ftoi(t); #else int st; @@ -2802,7 +2804,7 @@ static void gen_cast(CType *type) /* need to convert from 32bit to 64bit */ gv(RC_INT); if (sbt != (VT_INT | VT_UNSIGNED)) { -#if defined(TCC_TARGET_ARM64) +#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_RISCV64) gen_cvt_sxtw(); #elif defined(TCC_TARGET_X86_64) int r = gv(RC_INT); @@ -5469,12 +5471,14 @@ special_math_val: #endif } else { #ifndef TCC_TARGET_ARM64 +#ifndef TCC_TARGET_RISCV64 #ifdef TCC_TARGET_X86_64 if ((ret.type.t & VT_BTYPE) == VT_QLONG) #else if ((ret.type.t & VT_BTYPE) == VT_LLONG) #endif ret.r2 = REG_LRET; +#endif #endif ret.r = REG_IRET; } @@ -6015,6 +6019,7 @@ ST_FUNC int expr_const(void) /* return from function */ #ifndef TCC_TARGET_ARM64 +#ifndef TCC_TARGET_RISCV64 static void gfunc_return(CType *func_type) { if ((func_type->t & VT_BTYPE) == VT_STRUCT) { @@ -6079,6 +6084,7 @@ static void gfunc_return(CType *func_type) vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ } #endif +#endif static void check_func_return(void) {