Unified · Split
| @@ -78,6 +78,7 @@ NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT · 77 unmodified lines | ||
| 78 | 78 | NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI |
| 79 | 79 | NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP |
| 80 | 80 | NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64 |
| 81 | +NATIVE_DEFINES_$(CONFIG_riscv64) += -DTCC_TARGET_RISCV64 | |
| 81 | 82 | NATIVE_DEFINES += $(NATIVE_DEFINES_yes) |
| 82 | 83 | |
| 83 | 84 | ifeq ($(INCLUDED),no) |
| @@ -92,10 +93,12 @@ all: $(PROGS) $(TCCLIBS) $(TCCDOCS) · 8 unmodified lines | ||
| 92 | 93 | |
| 93 | 94 | # cross compiler targets to build |
| 94 | 95 | TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67 |
| 96 | +TCC_X += riscv64 | |
| 95 | 97 | # TCC_X += arm-fpa arm-fpa-ld arm-vfp arm-eabi |
| 96 | 98 | |
| 97 | 99 | # cross libtcc1.a targets to build |
| 98 | 100 | LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince |
| 101 | +LIBTCC1_X = riscv64 | |
| 99 | 102 | |
| 100 | 103 | PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF)) |
| 101 | 104 | LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a) |
| @@ -133,6 +136,7 @@ DEF-arm-vfp = -DTCC_TARGET_ARM -DTCC_ARM_VFP · 31 unmodified lines | ||
| 133 | 136 | DEF-arm-eabi = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI |
| 134 | 137 | DEF-arm-eabihf = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT |
| 135 | 138 | DEF-arm = $(DEF-arm-eabihf) |
| 139 | +DEF-riscv64 = -DTCC_TARGET_RISCV64 | |
| 136 | 140 | DEF-$(NATIVE_TARGET) = $(NATIVE_DEFINES) |
| 137 | 141 | |
| 138 | 142 | DEFINES += $(DEF-$T) $(DEF-all) |
| @@ -172,6 +176,7 @@ arm-eabi_FILES = $(arm_FILES) · 33 unmodified lines | ||
| 172 | 176 | arm-eabihf_FILES = $(arm_FILES) |
| 173 | 177 | arm64_FILES = $(CORE_FILES) arm64-gen.c arm64-link.c |
| 174 | 178 | c67_FILES = $(CORE_FILES) c67-gen.c c67-link.c tcccoff.c |
| 179 | +riscv64_FILES = $(CORE_FILES) riscv64-gen.c riscv64-link.c | |
| 175 | 180 | |
| 176 | 181 | # libtcc sources |
| 177 | 182 | LIBTCC_SRC = $(filter-out tcc.c tcctools.c,$(filter %.c,$($T_FILES))) |
| @@ -232,6 +232,9 @@ case "$cpu" in · 231 unmodified lines | ||
| 232 | 232 | s390) |
| 233 | 233 | cpu="s390" |
| 234 | 234 | ;; |
| 235 | + riscv64) | |
| 236 | + cpu="riscv64" | |
| 237 | + ;; | |
| 235 | 238 | *) |
| 236 | 239 | echo "Unsupported CPU" |
| 237 | 240 | exit 1 |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | # define TRIPLET_ARCH "arm" |
| 14 | 14 | #elif defined(__aarch64__) |
| 15 | 15 | # define TRIPLET_ARCH "aarch64" |
| 16 | +#elif defined(__riscv) && defined(__LP64__) | |
| 17 | +# define TRIPLET_ARCH "riscv64" | |
| 16 | 18 | #else |
| 17 | 19 | # define TRIPLET_ARCH "unknown" |
| 18 | 20 | #endif |
| @@ -262,7 +262,8 @@ typedef struct · 261 unmodified lines | ||
| 262 | 262 | #define EM_AARCH64 183 /* ARM AARCH64 */ |
| 263 | 263 | #define EM_TILEPRO 188 /* Tilera TILEPro */ |
| 264 | 264 | #define EM_TILEGX 191 /* Tilera TILE-Gx */ |
| 265 | −#define EM_NUM 192 | |
| 265 | +#define EM_RISCV 243 /* RISC-V */ | |
| 266 | +#define EM_NUM 253 | |
| 266 | 267 | |
| 267 | 268 | /* If it is necessary to assign new unofficial EM_* values, please |
| 268 | 269 | pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the |
| @@ -381,7 +382,7 @@ typedef struct · 112 unmodified lines | ||
| 381 | 382 | #define SHF_MASKPROC 0xf0000000 /* Processor-specific */ |
| 382 | 383 | #define SHF_ORDERED (1 << 30) /* Special ordering requirement |
| 383 | 384 | (Solaris). */ |
| 384 | −#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless | |
| 385 | +#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless | |
| 385 | 386 | referenced or allocated (Solaris).*/ |
| 386 | 387 | |
| 387 | 388 | /* Section group handling. */ |
| @@ -3233,5 +3234,71 @@ typedef Elf32_Addr Elf32_Conflict; · 2845 unmodified lines | ||
| 3233 | 3234 | |
| 3234 | 3235 | #define R_TILEGX_NUM 130 |
| 3235 | 3236 | |
| 3237 | +/* RISC-V ELF Flags */ | |
| 3238 | +#define EF_RISCV_RVC 0x0001 | |
| 3239 | +#define EF_RISCV_FLOAT_ABI 0x0006 | |
| 3240 | +#define EF_RISCV_FLOAT_ABI_SOFT 0x0000 | |
| 3241 | +#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002 | |
| 3242 | +#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004 | |
| 3243 | +#define EF_RISCV_FLOAT_ABI_QUAD 0x0006 | |
| 3244 | + | |
| 3245 | +/* RISC-V relocations. */ | |
| 3246 | +#define R_RISCV_NONE 0 | |
| 3247 | +#define R_RISCV_32 1 | |
| 3248 | +#define R_RISCV_64 2 | |
| 3249 | +#define R_RISCV_RELATIVE 3 | |
| 3250 | +#define R_RISCV_COPY 4 | |
| 3251 | +#define R_RISCV_JUMP_SLOT 5 | |
| 3252 | +#define R_RISCV_TLS_DTPMOD32 6 | |
| 3253 | +#define R_RISCV_TLS_DTPMOD64 7 | |
| 3254 | +#define R_RISCV_TLS_DTPREL32 8 | |
| 3255 | +#define R_RISCV_TLS_DTPREL64 9 | |
| 3256 | +#define R_RISCV_TLS_TPREL32 10 | |
| 3257 | +#define R_RISCV_TLS_TPREL64 11 | |
| 3258 | +#define R_RISCV_BRANCH 16 | |
| 3259 | +#define R_RISCV_JAL 17 | |
| 3260 | +#define R_RISCV_CALL 18 | |
| 3261 | +#define R_RISCV_CALL_PLT 19 | |
| 3262 | +#define R_RISCV_GOT_HI20 20 | |
| 3263 | +#define R_RISCV_TLS_GOT_HI20 21 | |
| 3264 | +#define R_RISCV_TLS_GD_HI20 22 | |
| 3265 | +#define R_RISCV_PCREL_HI20 23 | |
| 3266 | +#define R_RISCV_PCREL_LO12_I 24 | |
| 3267 | +#define R_RISCV_PCREL_LO12_S 25 | |
| 3268 | +#define R_RISCV_HI20 26 | |
| 3269 | +#define R_RISCV_LO12_I 27 | |
| 3270 | +#define R_RISCV_LO12_S 28 | |
| 3271 | +#define R_RISCV_TPREL_HI20 29 | |
| 3272 | +#define R_RISCV_TPREL_LO12_I 30 | |
| 3273 | +#define R_RISCV_TPREL_LO12_S 31 | |
| 3274 | +#define R_RISCV_TPREL_ADD 32 | |
| 3275 | +#define R_RISCV_ADD8 33 | |
| 3276 | +#define R_RISCV_ADD16 34 | |
| 3277 | +#define R_RISCV_ADD32 35 | |
| 3278 | +#define R_RISCV_ADD64 36 | |
| 3279 | +#define R_RISCV_SUB8 37 | |
| 3280 | +#define R_RISCV_SUB16 38 | |
| 3281 | +#define R_RISCV_SUB32 39 | |
| 3282 | +#define R_RISCV_SUB64 40 | |
| 3283 | +#define R_RISCV_GNU_VTINHERIT 41 | |
| 3284 | +#define R_RISCV_GNU_VTENTRY 42 | |
| 3285 | +#define R_RISCV_ALIGN 43 | |
| 3286 | +#define R_RISCV_RVC_BRANCH 44 | |
| 3287 | +#define R_RISCV_RVC_JUMP 45 | |
| 3288 | +#define R_RISCV_RVC_LUI 46 | |
| 3289 | +#define R_RISCV_GPREL_I 47 | |
| 3290 | +#define R_RISCV_GPREL_S 48 | |
| 3291 | +#define R_RISCV_TPREL_I 49 | |
| 3292 | +#define R_RISCV_TPREL_S 50 | |
| 3293 | +#define R_RISCV_RELAX 51 | |
| 3294 | +#define R_RISCV_SUB6 52 | |
| 3295 | +#define R_RISCV_SET6 53 | |
| 3296 | +#define R_RISCV_SET8 54 | |
| 3297 | +#define R_RISCV_SET16 55 | |
| 3298 | +#define R_RISCV_SET32 56 | |
| 3299 | +#define R_RISCV_32_PCREL 57 | |
| 3300 | + | |
| 3301 | +#define R_RISCV_NUM 58 | |
| 3302 | + | |
| 3236 | 3303 | |
| 3237 | 3304 | #endif /* elf.h */ |
| @@ -43,6 +43,7 @@ I386_O = libtcc1.o alloca86.o alloca86-bt.o · 42 unmodified lines | ||
| 43 | 43 | X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o |
| 44 | 44 | ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o |
| 45 | 45 | ARM64_O = lib-arm64.o |
| 46 | +RISCV64_O = | |
| 46 | 47 | WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o |
| 47 | 48 | |
| 48 | 49 | OBJ-i386 = $(I386_O) $(BCHECK_O) $(DSO_O) |
| @@ -58,6 +59,7 @@ OBJ-arm-vfp = $(ARM_O) $(DSO_O) · 9 unmodified lines | ||
| 58 | 59 | OBJ-arm-eabi = $(ARM_O) $(DSO_O) |
| 59 | 60 | OBJ-arm-eabihf = $(ARM_O) $(DSO_O) |
| 60 | 61 | OBJ-arm-wince = $(ARM_O) $(WIN_O) |
| 62 | +OBJ-riscv64 = $(RISCV64_O) $(DSO_O) | |
| 61 | 63 | |
| 62 | 64 | $(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T)) |
| 63 | 65 | $(XAR) rcs $@ $^ |
| @@ -45,25 +45,26 @@ static int nb_states; · 44 unmodified lines | ||
| 45 | 45 | #include "i386-gen.c" |
| 46 | 46 | #include "i386-link.c" |
| 47 | 47 | #include "i386-asm.c" |
| 48 | −#endif | |
| 49 | −#ifdef TCC_TARGET_ARM | |
| 48 | +#elif defined(TCC_TARGET_ARM) | |
| 50 | 49 | #include "arm-gen.c" |
| 51 | 50 | #include "arm-link.c" |
| 52 | 51 | #include "arm-asm.c" |
| 53 | −#endif | |
| 54 | −#ifdef TCC_TARGET_ARM64 | |
| 52 | +#elif defined(TCC_TARGET_ARM64) | |
| 55 | 53 | #include "arm64-gen.c" |
| 56 | 54 | #include "arm64-link.c" |
| 57 | −#endif | |
| 58 | −#ifdef TCC_TARGET_C67 | |
| 55 | +#elif defined(TCC_TARGET_C67) | |
| 59 | 56 | #include "c67-gen.c" |
| 60 | 57 | #include "c67-link.c" |
| 61 | 58 | #include "tcccoff.c" |
| 62 | −#endif | |
| 63 | −#ifdef TCC_TARGET_X86_64 | |
| 59 | +#elif defined(TCC_TARGET_X86_64) | |
| 64 | 60 | #include "x86_64-gen.c" |
| 65 | 61 | #include "x86_64-link.c" |
| 66 | 62 | #include "i386-asm.c" |
| 63 | +#elif defined(TCC_TARGET_RISCV64) | |
| 64 | +#include "riscv64-gen.c" | |
| 65 | +#include "riscv64-link.c" | |
| 66 | +#else | |
| 67 | +#error unknown target | |
| 67 | 68 | #endif |
| 68 | 69 | #ifdef CONFIG_TCC_ASM |
| 69 | 70 | #include "tccasm.c" |
| @@ -0,0 +1,193 @@ | ||
| 1 | +#ifdef TARGET_DEFS_ONLY | |
| 2 | + | |
| 3 | +// Number of registers available to allocator: | |
| 4 | +#define NB_REGS 16 // x10-x17 aka a0-a7, f10-f17 aka fa0-fa7 | |
| 5 | + | |
| 6 | +#define TREG_R(x) (x) // x = 0..7 | |
| 7 | +#define TREG_F(x) (x + 10) // x = 0..7 | |
| 8 | + | |
| 9 | +// Register classes sorted from more general to more precise: | |
| 10 | +#define RC_INT (1 << 0) | |
| 11 | +#define RC_FLOAT (1 << 1) | |
| 12 | +#define RC_R(x) (1 << (2 + (x))) // x = 0..7 | |
| 13 | +#define RC_F(x) (1 << (10 + (x))) // x = 0..7 | |
| 14 | + | |
| 15 | +#define RC_IRET (RC_R(0)) // int return register class | |
| 16 | +#define RC_FRET (RC_F(0)) // float return register class | |
| 17 | + | |
| 18 | +#define REG_IRET (TREG_R(0)) // int return register number | |
| 19 | +#define REG_FRET (TREG_F(0)) // float return register number | |
| 20 | + | |
| 21 | +#define PTR_SIZE 8 | |
| 22 | + | |
| 23 | +#define LDOUBLE_SIZE 16 | |
| 24 | +#define LDOUBLE_ALIGN 16 | |
| 25 | + | |
| 26 | +#define MAX_ALIGN 16 | |
| 27 | + | |
| 28 | +#define CHAR_IS_UNSIGNED | |
| 29 | + | |
| 30 | +#else | |
| 31 | +#include "tcc.h" | |
| 32 | + | |
| 33 | +ST_DATA const int reg_classes[NB_REGS] = { | |
| 34 | + RC_INT | RC_R(0), | |
| 35 | + RC_INT | RC_R(1), | |
| 36 | + RC_INT | RC_R(2), | |
| 37 | + RC_INT | RC_R(3), | |
| 38 | + RC_INT | RC_R(4), | |
| 39 | + RC_INT | RC_R(5), | |
| 40 | + RC_INT | RC_R(6), | |
| 41 | + RC_INT | RC_R(7), | |
| 42 | + RC_FLOAT | RC_F(0), | |
| 43 | + RC_FLOAT | RC_F(1), | |
| 44 | + RC_FLOAT | RC_F(2), | |
| 45 | + RC_FLOAT | RC_F(3), | |
| 46 | + RC_FLOAT | RC_F(4), | |
| 47 | + RC_FLOAT | RC_F(5), | |
| 48 | + RC_FLOAT | RC_F(6), | |
| 49 | + RC_FLOAT | RC_F(7) | |
| 50 | +}; | |
| 51 | + | |
| 52 | +// Patch all branches in list pointed to by t to branch to a: | |
| 53 | +ST_FUNC void gsym_addr(int t_, int a_) | |
| 54 | +{ | |
| 55 | + uint32_t t = t_; | |
| 56 | + uint32_t a = a_; | |
| 57 | + tcc_error("implement me"); | |
| 58 | + while (t) { | |
| 59 | + unsigned char *ptr = cur_text_section->data + t; | |
| 60 | + uint32_t next = read32le(ptr); | |
| 61 | + if (a - t + 0x8000000 >= 0x10000000) | |
| 62 | + tcc_error("branch out of range"); | |
| 63 | + write32le(ptr, (a - t == 4 ? 0xd503201f : // nop | |
| 64 | + 0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b | |
| 65 | + t = next; | |
| 66 | + } | |
| 67 | +} | |
| 68 | + | |
| 69 | +ST_FUNC void load(int r, SValue *sv) | |
| 70 | +{ | |
| 71 | + tcc_error("implement me"); | |
| 72 | +} | |
| 73 | + | |
| 74 | +ST_FUNC void store(int r, SValue *sv) | |
| 75 | +{ | |
| 76 | + tcc_error("implement me"); | |
| 77 | +} | |
| 78 | + | |
| 79 | +ST_FUNC void gfunc_call(int nb_args) | |
| 80 | +{ | |
| 81 | + tcc_error("implement me"); | |
| 82 | +} | |
| 83 | +ST_FUNC void gfunc_prolog(CType *func_type) | |
| 84 | +{ | |
| 85 | + tcc_error("implement me"); | |
| 86 | +} | |
| 87 | +ST_FUNC void gen_va_start(void) | |
| 88 | +{ | |
| 89 | + tcc_error("implement me"); | |
| 90 | +} | |
| 91 | +ST_FUNC void gen_va_arg(CType *t) | |
| 92 | +{ | |
| 93 | + tcc_error("implement me"); | |
| 94 | +} | |
| 95 | +ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, | |
| 96 | + int *align, int *regsize) | |
| 97 | +{ | |
| 98 | + tcc_error("implement me"); | |
| 99 | +} | |
| 100 | +ST_FUNC void gfunc_return(CType *func_type) | |
| 101 | +{ | |
| 102 | + tcc_error("implement me"); | |
| 103 | +} | |
| 104 | +ST_FUNC void gfunc_epilog(void) | |
| 105 | +{ | |
| 106 | + tcc_error("implement me"); | |
| 107 | +} | |
| 108 | +ST_FUNC void gen_fill_nops(int bytes) | |
| 109 | +{ | |
| 110 | + tcc_error("implement me"); | |
| 111 | + if ((bytes & 3)) | |
| 112 | + tcc_error("alignment of code section not multiple of 4"); | |
| 113 | +} | |
| 114 | + | |
| 115 | +// Generate forward branch to label: | |
| 116 | +ST_FUNC int gjmp(int t) | |
| 117 | +{ | |
| 118 | + tcc_error("implement me"); | |
| 119 | +} | |
| 120 | + | |
| 121 | +// Generate branch to known address: | |
| 122 | +ST_FUNC void gjmp_addr(int a) | |
| 123 | +{ | |
| 124 | + tcc_error("implement me"); | |
| 125 | +} | |
| 126 | + | |
| 127 | +ST_FUNC int gjmp_cond(int op, int t) | |
| 128 | +{ | |
| 129 | + tcc_error("implement me"); | |
| 130 | +} | |
| 131 | + | |
| 132 | +ST_FUNC int gjmp_append(int n, int t) | |
| 133 | +{ | |
| 134 | + tcc_error("implement me"); | |
| 135 | +} | |
| 136 | + | |
| 137 | +ST_FUNC int gtst(int inv, int t) | |
| 138 | +{ | |
| 139 | + tcc_error("implement me"); | |
| 140 | +} | |
| 141 | +ST_FUNC void gen_opi(int op) | |
| 142 | +{ | |
| 143 | + tcc_error("implement me"); | |
| 144 | +} | |
| 145 | + | |
| 146 | +ST_FUNC void gen_opl(int op) | |
| 147 | +{ | |
| 148 | + tcc_error("implement me"); | |
| 149 | +} | |
| 150 | + | |
| 151 | +ST_FUNC void gen_opf(int op) | |
| 152 | +{ | |
| 153 | + tcc_error("implement me"); | |
| 154 | +} | |
| 155 | +ST_FUNC void gen_cvt_sxtw(void) | |
| 156 | +{ | |
| 157 | + tcc_error("implement me"); | |
| 158 | +} | |
| 159 | + | |
| 160 | +ST_FUNC void gen_cvt_itof(int t) | |
| 161 | +{ | |
| 162 | + tcc_error("implement me"); | |
| 163 | +} | |
| 164 | + | |
| 165 | +ST_FUNC void gen_cvt_ftoi(int t) | |
| 166 | +{ | |
| 167 | + tcc_error("implement me"); | |
| 168 | +} | |
| 169 | + | |
| 170 | +ST_FUNC void gen_cvt_ftof(int t) | |
| 171 | +{ | |
| 172 | + tcc_error("implement me"); | |
| 173 | +} | |
| 174 | + | |
| 175 | +ST_FUNC void ggoto(void) | |
| 176 | +{ | |
| 177 | + tcc_error("implement me"); | |
| 178 | +} | |
| 179 | +ST_FUNC void gen_vla_sp_save(int addr) | |
| 180 | +{ | |
| 181 | + tcc_error("implement me"); | |
| 182 | +} | |
| 183 | + | |
| 184 | +ST_FUNC void gen_vla_sp_restore(int addr) | |
| 185 | +{ | |
| 186 | + tcc_error("implement me"); | |
| 187 | +} | |
| 188 | + | |
| 189 | +ST_FUNC void gen_vla_alloc(CType *type, int align) | |
| 190 | +{ | |
| 191 | + tcc_error("implement me"); | |
| 192 | +} | |
| 193 | +#endif | |
| @@ -0,0 +1,122 @@ | ||
| 1 | +#ifdef TARGET_DEFS_ONLY | |
| 2 | + | |
| 3 | +#define EM_TCC_TARGET EM_RISCV | |
| 4 | + | |
| 5 | +#define R_DATA_32 R_RISCV_32 | |
| 6 | +#define R_DATA_PTR R_RISCV_64 | |
| 7 | +#define R_JMP_SLOT R_RISCV_JUMP_SLOT | |
| 8 | +#define R_GLOB_DAT R_RISCV_64 | |
| 9 | +#define R_COPY R_RISCV_COPY | |
| 10 | +#define R_RELATIVE R_RISCV_RELATIVE | |
| 11 | + | |
| 12 | +#define R_NUM R_RISCV_NUM | |
| 13 | + | |
| 14 | +#define ELF_START_ADDR 0x00010000 | |
| 15 | +#define ELF_PAGE_SIZE 0x1000 | |
| 16 | + | |
| 17 | +#define PCRELATIVE_DLLPLT 1 | |
| 18 | +#define RELOCATE_DLLPLT 1 | |
| 19 | + | |
| 20 | +#else /* !TARGET_DEFS_ONLY */ | |
| 21 | + | |
| 22 | +#include "tcc.h" | |
| 23 | + | |
| 24 | +/* Returns 1 for a code relocation, 0 for a data relocation. For unknown | |
| 25 | + relocations, returns -1. */ | |
| 26 | +int code_reloc (int reloc_type) | |
| 27 | +{ | |
| 28 | + switch (reloc_type) { | |
| 29 | + } | |
| 30 | + tcc_error ("Unknown relocation type: %d", reloc_type); | |
| 31 | + return -1; | |
| 32 | +} | |
| 33 | + | |
| 34 | +/* Returns an enumerator to describe whether and when the relocation needs a | |
| 35 | + GOT and/or PLT entry to be created. See tcc.h for a description of the | |
| 36 | + different values. */ | |
| 37 | +int gotplt_entry_type (int reloc_type) | |
| 38 | +{ | |
| 39 | + switch (reloc_type) { | |
| 40 | + } | |
| 41 | + | |
| 42 | + tcc_error ("Unknown relocation type: %d", reloc_type); | |
| 43 | + return -1; | |
| 44 | +} | |
| 45 | + | |
| 46 | +ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) | |
| 47 | +{ | |
| 48 | + Section *plt = s1->plt; | |
| 49 | + uint8_t *p; | |
| 50 | + unsigned plt_offset; | |
| 51 | + | |
| 52 | + if (s1->output_type == TCC_OUTPUT_DLL) | |
| 53 | + tcc_error("DLLs unimplemented!"); | |
| 54 | + | |
| 55 | + if (plt->data_offset == 0) | |
| 56 | + section_ptr_add(plt, 32); | |
| 57 | + plt_offset = plt->data_offset; | |
| 58 | + | |
| 59 | + p = section_ptr_add(plt, 16); | |
| 60 | + write64le(p, got_offset); | |
| 61 | + return plt_offset; | |
| 62 | +} | |
| 63 | + | |
| 64 | +/* relocate the PLT: compute addresses and offsets in the PLT now that final | |
| 65 | + address for PLT and GOT are known (see fill_program_header) */ | |
| 66 | +ST_FUNC void relocate_plt(TCCState *s1) | |
| 67 | +{ | |
| 68 | + uint8_t *p, *p_end; | |
| 69 | + | |
| 70 | + if (!s1->plt) | |
| 71 | + return; | |
| 72 | + | |
| 73 | + p = s1->plt->data; | |
| 74 | + p_end = p + s1->plt->data_offset; | |
| 75 | + | |
| 76 | + if (p < p_end) { | |
| 77 | + uint64_t plt = s1->plt->sh_addr; | |
| 78 | + uint64_t got = s1->got->sh_addr; | |
| 79 | + uint64_t off = (got >> 12) - (plt >> 12); | |
| 80 | + if ((off + ((uint32_t)1 << 20)) >> 21) | |
| 81 | + tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt); | |
| 82 | + write32le(p, 0x0); | |
| 83 | + write32le(p + 4, 0x0); | |
| 84 | + write32le(p + 8, 0x0); | |
| 85 | + write32le(p + 12, 0x0); | |
| 86 | + write32le(p + 16, 0x0); | |
| 87 | + write32le(p + 20, 0x0); | |
| 88 | + write32le(p + 24, 0x0); | |
| 89 | + write32le(p + 28, 0x0); | |
| 90 | + p += 32; | |
| 91 | + while (p < p_end) { | |
| 92 | + uint64_t pc = plt + (p - s1->plt->data); | |
| 93 | + uint64_t addr = got + read64le(p); | |
| 94 | + uint64_t off = (addr >> 12) - (pc >> 12); | |
| 95 | + if ((off + ((uint32_t)1 << 20)) >> 21) | |
| 96 | + tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc); | |
| 97 | + write32le(p, 0x0); | |
| 98 | + write32le(p + 4, 0x0); | |
| 99 | + write32le(p + 8, 0x0); | |
| 100 | + write32le(p + 12, 0x0); | |
| 101 | + p += 16; | |
| 102 | + } | |
| 103 | + } | |
| 104 | +} | |
| 105 | + | |
| 106 | +void relocate_init(Section *sr) {} | |
| 107 | + | |
| 108 | +void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) | |
| 109 | +{ | |
| 110 | + int sym_index = ELFW(R_SYM)(rel->r_info); | |
| 111 | +#ifdef DEBUG_RELOC | |
| 112 | + ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | |
| 113 | +#endif | |
| 114 | + | |
| 115 | + switch(type) { | |
| 116 | + default: | |
| 117 | + fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n", | |
| 118 | + type, (unsigned)addr, ptr, (unsigned)val); | |
| 119 | + return; | |
| 120 | + } | |
| 121 | +} | |
| 122 | +#endif | |
| @@ -139,11 +139,12 @@ extern long double strtold (const char *__nptr, char **__endptr); · 138 unmodified lines | ||
| 139 | 139 | /* #define TCC_TARGET_ARM *//* ARMv4 code generator */ |
| 140 | 140 | /* #define TCC_TARGET_ARM64 *//* ARMv8 code generator */ |
| 141 | 141 | /* #define TCC_TARGET_C67 *//* TMS320C67xx code generator */ |
| 142 | +/* #define TCC_TARGET_RISCV64 *//* risc-v code generator */ | |
| 142 | 143 | |
| 143 | 144 | /* default target is I386 */ |
| 144 | 145 | #if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \ |
| 145 | 146 | !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \ |
| 146 | − !defined(TCC_TARGET_X86_64) | |
| 147 | + !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_RISCV64) | |
| 147 | 148 | # if defined __x86_64__ |
| 148 | 149 | # define TCC_TARGET_X86_64 |
| 149 | 150 | # elif defined __arm__ |
| @@ -170,6 +171,8 @@ extern long double strtold (const char *__nptr, char **__endptr); · 20 unmodified lines | ||
| 170 | 171 | # define TCC_IS_NATIVE |
| 171 | 172 | # elif defined __aarch64__ && defined TCC_TARGET_ARM64 |
| 172 | 173 | # define TCC_IS_NATIVE |
| 174 | +# elif defined __riscv && defined __LP64__ && defined TCC_TARGET_RISCV64 | |
| 175 | +# define TCC_IS_NATIVE | |
| 173 | 176 | # endif |
| 174 | 177 | #endif |
| 175 | 178 | |
| @@ -330,25 +333,26 @@ extern long double strtold (const char *__nptr, char **__endptr); · 154 unmodified lines | ||
| 330 | 333 | #ifdef TCC_TARGET_I386 |
| 331 | 334 | # include "i386-gen.c" |
| 332 | 335 | # include "i386-link.c" |
| 333 | −#endif | |
| 334 | −#ifdef TCC_TARGET_X86_64 | |
| 336 | +#elif defined TCC_TARGET_X86_64 | |
| 335 | 337 | # include "x86_64-gen.c" |
| 336 | 338 | # include "x86_64-link.c" |
| 337 | −#endif | |
| 338 | −#ifdef TCC_TARGET_ARM | |
| 339 | +#elif defined TCC_TARGET_ARM | |
| 339 | 340 | # include "arm-gen.c" |
| 340 | 341 | # include "arm-link.c" |
| 341 | 342 | # include "arm-asm.c" |
| 342 | −#endif | |
| 343 | −#ifdef TCC_TARGET_ARM64 | |
| 343 | +#elif defined TCC_TARGET_ARM64 | |
| 344 | 344 | # include "arm64-gen.c" |
| 345 | 345 | # include "arm64-link.c" |
| 346 | −#endif | |
| 347 | −#ifdef TCC_TARGET_C67 | |
| 346 | +#elif defined TCC_TARGET_C67 | |
| 348 | 347 | # define TCC_TARGET_COFF |
| 349 | 348 | # include "coff.h" |
| 350 | 349 | # include "c67-gen.c" |
| 351 | 350 | # include "c67-link.c" |
| 351 | +#elif defined(TCC_TARGET_RISCV64) | |
| 352 | +# include "riscv64-gen.c" | |
| 353 | +# include "riscv64-link.c" | |
| 354 | +#else | |
| 355 | +#error unknown target | |
| 352 | 356 | #endif |
| 353 | 357 | #undef TARGET_DEFS_ONLY |
| 354 | 358 | |
| @@ -1594,6 +1598,14 @@ ST_FUNC void gen_va_arg(CType *t); · 1239 unmodified lines | ||
| 1594 | 1598 | ST_FUNC void gen_clear_cache(void); |
| 1595 | 1599 | #endif |
| 1596 | 1600 | |
| 1601 | +/* ------------ riscv64-gen.c ------------ */ | |
| 1602 | +#ifdef TCC_TARGET_RISCV64 | |
| 1603 | +ST_FUNC void gen_cvt_sxtw(void); | |
| 1604 | +ST_FUNC void gen_opl(int op); | |
| 1605 | +ST_FUNC void gfunc_return(CType *func_type); | |
| 1606 | +ST_FUNC void gen_va_start(void); | |
| 1607 | +ST_FUNC void gen_va_arg(CType *t); | |
| 1608 | +#endif | |
| 1597 | 1609 | /* ------------ c67-gen.c ------------ */ |
| 1598 | 1610 | #ifdef TCC_TARGET_C67 |
| 1599 | 1611 | #endif |
| @@ -1548,12 +1548,14 @@ ST_FUNC int gv(int rc) · 1547 unmodified lines | ||
| 1548 | 1548 | r = vtop->r & VT_VALMASK; |
| 1549 | 1549 | rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT; |
| 1550 | 1550 | #ifndef TCC_TARGET_ARM64 |
| 1551 | +#ifndef TCC_TARGET_RISCV64 /* XXX: remove the whole LRET/QRET class */ | |
| 1551 | 1552 | if (rc == RC_IRET) |
| 1552 | 1553 | rc2 = RC_LRET; |
| 1553 | 1554 | #ifdef TCC_TARGET_X86_64 |
| 1554 | 1555 | else if (rc == RC_FRET) |
| 1555 | 1556 | rc2 = RC_QRET; |
| 1556 | 1557 | #endif |
| 1558 | +#endif | |
| 1557 | 1559 | #endif |
| 1558 | 1560 | /* need to reload if: |
| 1559 | 1561 | - constant |
| @@ -2552,7 +2554,7 @@ redo: · 992 unmodified lines | ||
| 2552 | 2554 | /* generic itof for unsigned long long case */ |
| 2553 | 2555 | static void gen_cvt_itof1(int t) |
| 2554 | 2556 | { |
| 2555 | −#ifdef TCC_TARGET_ARM64 | |
| 2557 | +#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 | |
| 2556 | 2558 | gen_cvt_itof(t); |
| 2557 | 2559 | #else |
| 2558 | 2560 | if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == |
| @@ -2580,7 +2582,7 @@ static void gen_cvt_itof1(int t) · 21 unmodified lines | ||
| 2580 | 2582 | /* generic ftoi for unsigned long long case */ |
| 2581 | 2583 | static void gen_cvt_ftoi1(int t) |
| 2582 | 2584 | { |
| 2583 | −#ifdef TCC_TARGET_ARM64 | |
| 2585 | +#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64 | |
| 2584 | 2586 | gen_cvt_ftoi(t); |
| 2585 | 2587 | #else |
| 2586 | 2588 | int st; |
| @@ -2802,7 +2804,7 @@ static void gen_cast(CType *type) · 215 unmodified lines | ||
| 2802 | 2804 | /* need to convert from 32bit to 64bit */ |
| 2803 | 2805 | gv(RC_INT); |
| 2804 | 2806 | if (sbt != (VT_INT | VT_UNSIGNED)) { |
| 2805 | −#if defined(TCC_TARGET_ARM64) | |
| 2807 | +#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_RISCV64) | |
| 2806 | 2808 | gen_cvt_sxtw(); |
| 2807 | 2809 | #elif defined(TCC_TARGET_X86_64) |
| 2808 | 2810 | int r = gv(RC_INT); |
| @@ -5469,12 +5471,14 @@ special_math_val: · 2660 unmodified lines | ||
| 5469 | 5471 | #endif |
| 5470 | 5472 | } else { |
| 5471 | 5473 | #ifndef TCC_TARGET_ARM64 |
| 5474 | +#ifndef TCC_TARGET_RISCV64 | |
| 5472 | 5475 | #ifdef TCC_TARGET_X86_64 |
| 5473 | 5476 | if ((ret.type.t & VT_BTYPE) == VT_QLONG) |
| 5474 | 5477 | #else |
| 5475 | 5478 | if ((ret.type.t & VT_BTYPE) == VT_LLONG) |
| 5476 | 5479 | #endif |
| 5477 | 5480 | ret.r2 = REG_LRET; |
| 5481 | +#endif | |
| 5478 | 5482 | #endif |
| 5479 | 5483 | ret.r = REG_IRET; |
| 5480 | 5484 | } |
| @@ -6015,6 +6019,7 @@ ST_FUNC int expr_const(void) · 534 unmodified lines | ||
| 6015 | 6019 | /* return from function */ |
| 6016 | 6020 | |
| 6017 | 6021 | #ifndef TCC_TARGET_ARM64 |
| 6022 | +#ifndef TCC_TARGET_RISCV64 | |
| 6018 | 6023 | static void gfunc_return(CType *func_type) |
| 6019 | 6024 | { |
| 6020 | 6025 | if ((func_type->t & VT_BTYPE) == VT_STRUCT) { |
| @@ -6079,6 +6084,7 @@ static void gfunc_return(CType *func_type) · 58 unmodified lines | ||
| 6079 | 6084 | vtop--; /* NOT vpop() because on x86 it would flush the fp stack */ |
| 6080 | 6085 | } |
| 6081 | 6086 | #endif |
| 6087 | +#endif | |
| 6082 | 6088 | |
| 6083 | 6089 | static void check_func_return(void) |
| 6084 | 6090 | { |