Compare commits
95 Commits
Author | SHA1 | Date |
---|---|---|
Alexander Sosedkin | 7b74b2733c | |
Ekaitz | 743710064f | |
Andrius Štikonas | 691ee7dd19 | |
Ekaitz | c3b3d422b1 | |
Ekaitz | 72c3d38814 | |
Ekaitz | 5a0ef8d062 | |
Andrius Štikonas | f636cf3d48 | |
Ekaitz | 900be40e8b | |
Ekaitz | dc52a81586 | |
Ekaitz | 613c511c56 | |
Ekaitz | a7f3da3345 | |
Andrius Štikonas | 29ac0f40a7 | |
Ekaitz | 4cf19b8b3b | |
Ekaitz | c9e425682e | |
Ekaitz | 53def017f6 | |
Ekaitz | 6fbd17852a | |
Ekaitz | aa727e57d2 | |
Ekaitz | 3b114c1fbd | |
Ekaitz | 1e597f3d23 | |
Ekaitz | c0df75653d | |
Andrius Štikonas | 772bfa5329 | |
Andrius Štikonas | ee274e0d0c | |
Juliana Sims | ac6f6ca36d | |
Ekaitz | 420559f392 | |
Ekaitz | 74fa23f5a4 | |
Ekaitz | 928c097cab | |
Ekaitz | aec9569801 | |
Ekaitz | 9d5859e57b | |
Ekaitz | 0e3f4c86d7 | |
Ekaitz | 7b0774f67b | |
Ekaitz | f67c2a680f | |
Ekaitz | c0b50a25a2 | |
Ekaitz | ef55a31795 | |
Ekaitz | 8a11993952 | |
Ekaitz | ac0c6844e0 | |
Ekaitz | ce78388547 | |
Ekaitz | 2c8ed6b6cd | |
Ekaitz | 726fbc56e9 | |
Ekaitz | 1de3a740d6 | |
Ekaitz | a715171766 | |
Ekaitz | 452921d768 | |
Ekaitz | 5054ff8239 | |
Jan (janneke) Nieuwenhuizen | 5bba73ccca | |
Jan (janneke) Nieuwenhuizen | 9d675376ce | |
Jan (janneke) Nieuwenhuizen | 6b69b496ad | |
Jan (janneke) Nieuwenhuizen | 02c45923d5 | |
Jan (janneke) Nieuwenhuizen | aab73482fe | |
Jan (janneke) Nieuwenhuizen | ebd1a5941f | |
Jan (janneke) Nieuwenhuizen | 8d475711f1 | |
Jan (janneke) Nieuwenhuizen | 126174a3f6 | |
Jan (janneke) Nieuwenhuizen | b693ee0d30 | |
Jan (janneke) Nieuwenhuizen | 8aa1a0ac36 | |
Jan (janneke) Nieuwenhuizen | 7d55366627 | |
Jan (janneke) Nieuwenhuizen | 5eb85b0468 | |
Jan (janneke) Nieuwenhuizen | ad5a6bae59 | |
Jan Nieuwenhuizen | 1d4b206c45 | |
Jan (janneke) Nieuwenhuizen | 8c6f0c2c61 | |
Jan (janneke) Nieuwenhuizen | 523498ec01 | |
Jan (janneke) Nieuwenhuizen | 5334d68ee2 | |
Jan (janneke) Nieuwenhuizen | 2cb4f26e26 | |
Jan (janneke) Nieuwenhuizen | 2613fb5d63 | |
Jan (janneke) Nieuwenhuizen | fc93202abe | |
Jan (janneke) Nieuwenhuizen | 35c9c24614 | |
Jan (janneke) Nieuwenhuizen | bdec98dd01 | |
Jan (janneke) Nieuwenhuizen | 2556e10583 | |
Jan (janneke) Nieuwenhuizen | fcb48635ce | |
Jan (janneke) Nieuwenhuizen | d0608d0d68 | |
Jan (janneke) Nieuwenhuizen | f7e98b52a1 | |
Jan (janneke) Nieuwenhuizen | e23023ec8a | |
Jan (janneke) Nieuwenhuizen | 907479d7ff | |
Jan (janneke) Nieuwenhuizen | 33403a4011 | |
Jan (janneke) Nieuwenhuizen | 94fa1710aa | |
Jan (janneke) Nieuwenhuizen | 35ccd60989 | |
Jan (janneke) Nieuwenhuizen | 0334950c24 | |
Jan Nieuwenhuizen | 20b1a1d001 | |
Jan Nieuwenhuizen | 6e62e0e58b | |
Jan Nieuwenhuizen | 17df781f70 | |
Jan Nieuwenhuizen | ba1c47dbdb | |
Jan Nieuwenhuizen | 0585122eb1 | |
Jan Nieuwenhuizen | f90808b155 | |
Jan Nieuwenhuizen | 1063d5a0dc | |
Jan Nieuwenhuizen | 36c0af218f | |
Jan Nieuwenhuizen | ec63de4990 | |
Jan Nieuwenhuizen | cee58e0963 | |
Jan Nieuwenhuizen | 39de35689e | |
Jan Nieuwenhuizen | 2b6271d1d5 | |
Jan Nieuwenhuizen | 379c62d63f | |
Jan Nieuwenhuizen | 274bd060fd | |
Jan Nieuwenhuizen | 6ae9aa40c7 | |
Jan Nieuwenhuizen | a130ce1702 | |
Jan Nieuwenhuizen | de906df43a | |
Jan Nieuwenhuizen | 540ba0b456 | |
Jan Nieuwenhuizen | 306f6779ad | |
Jan Nieuwenhuizen | 9c97705c42 | |
Jan Nieuwenhuizen | 584478fca2 |
|
@ -54,3 +54,4 @@ tests/libtcc_test
|
|||
tests/vla_test
|
||||
tests/hello
|
||||
tests/tests2/fred.txt
|
||||
tests/tests2/*.1
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#export LIBRARY_PATH=/home/janneke/src/tinycc-seed
|
||||
#export INCLUDE_PATH=/home/janneke/src/mes/include
|
||||
|
||||
export C_INCLUDE_PATH=/home/janneke/src/mes/include
|
||||
export LIBRARY_PATH=/home/janneke/src/tinycc-seed
|
||||
|
||||
./configure --cc='mes-tcc -static' --cpu=i386
|
||||
make ONE_SOURCE=yes CPPFLAGS=-DONE_SOURCE=yes
|
33
Makefile
33
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)
|
||||
|
@ -91,11 +92,11 @@ TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
|
|||
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 = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67 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 = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince riscv64
|
||||
|
||||
PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
|
||||
LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),libtcc1-$X.a)
|
||||
|
@ -132,6 +133,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)
|
||||
|
@ -165,6 +167,7 @@ arm_FILES = $(CORE_FILES) arm-gen.c arm-link.c arm-asm.c
|
|||
arm-wince_FILES = $(arm_FILES) tccpe.c
|
||||
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 riscv64-asm.c
|
||||
|
||||
# libtcc sources
|
||||
LIBTCC_SRC = $(filter-out tcc.c tcctools.c,$(filter %.c,$($T_FILES)))
|
||||
|
@ -188,7 +191,7 @@ $(X)%.o : %.c $(LIBTCC_INC)
|
|||
$(X)tcc.o : tcctools.c
|
||||
|
||||
# Host Tiny C Compiler
|
||||
tcc$(EXESUF): tcc.o $(LIBTCC)
|
||||
$(PROGRAM_PREFIX)tcc$(EXESUF): tcc.o $(LIBTCC)
|
||||
$(CC) -o $@ $^ $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
|
||||
|
||||
# Cross Tiny C Compilers
|
||||
|
@ -390,3 +393,27 @@ help:
|
|||
|
||||
# --------------------------------------------------------------------------
|
||||
endif # ($(INCLUDED),no)
|
||||
|
||||
### dist
|
||||
.PHONY: dist
|
||||
|
||||
PACKAGE=tcc
|
||||
COMMIT=$(shell git describe --dirty)
|
||||
CVS_VERSION=$(COMMIT:release_%=%)
|
||||
TARBALL_VERSION=$(subst _,.,$(CVS_VERSION))
|
||||
TARBALL_DIR:=$(PACKAGE)-$(TARBALL_VERSION)
|
||||
TARBALL=$(TARBALL_DIR).tar.gz
|
||||
# Be friendly to Debian; avoid using EPOCH
|
||||
MTIME=$(shell git show HEAD --format=%ct --no-patch)
|
||||
# Reproducible tarball
|
||||
TAR_FLAGS=--sort=name --mtime=@$(MTIME) --owner=0 --group=0 --numeric-owner --mode=go=rX,u+rw,a-s
|
||||
|
||||
$(TARBALL):
|
||||
(git ls-files \
|
||||
--exclude=$(TARBALL_DIR); \
|
||||
echo $^ | tr ' ' '\n') \
|
||||
| tar $(TAR_FLAGS) \
|
||||
--transform=s,^,$(TARBALL_DIR)/,S -T- -cf- \
|
||||
| gzip -c --no-name > $@
|
||||
|
||||
dist: $(TARBALL)
|
||||
|
|
85
README
85
README
|
@ -1,3 +1,88 @@
|
|||
Bootstrappable TCC/TinyCC -- Tiny C Compiler's bootstrappable fork
|
||||
------------------------------------------------------------------
|
||||
|
||||
Bootstrappable TCC is a fork from mainline TCC development, that
|
||||
started spring 2017 from
|
||||
|
||||
commit 307b7b183d4ee56e74090b0e525d6a587840e31f
|
||||
Author: Aron BARATH <baratharon@caesar.elte.hu>
|
||||
Date: Tue May 16 07:03:26 2017 +0200
|
||||
|
||||
the R_X86_64_GOTOFF64 relocation was missing
|
||||
|
||||
and can be compiled by MesCC (https://gnu.org/s/mes).
|
||||
|
||||
Initially the plan was to make TinyCC itself "bootstrappable"
|
||||
(https://bootstrappable.org).
|
||||
|
||||
The best way to do so would be to gradually simplify the
|
||||
implementation of TinyCC by restricting the use of language constructs
|
||||
to a well-defined subset of C. In bootstrapping each stage or
|
||||
compiler adds functionality; a compiler that is written in itself --a
|
||||
so-called `self-hosting' compiler--is not considered to be
|
||||
bootstrappable.
|
||||
|
||||
At the time this vision was not received with much enthousiasm
|
||||
|
||||
https://lists.nongnu.org/archive/html/tinycc-devel/2017-09/msg00019.html
|
||||
|
||||
so I decided to fork TinyCC and instead grow MesCC (a bootstrappable
|
||||
sub-C compiler in a subset of Guile Scheme) into a full C99 compiler.
|
||||
|
||||
Currently, the Reduced Binary Seed Bootstrap of the GNU Guix System
|
||||
uses bootstrappable-tinycc. See
|
||||
https://guix.gnu.org/en/blog/2020/guix-further-reduces-bootstrap-seed-to-25/
|
||||
https://guix.gnu.org/blog/2019/guix-reduces-bootstrap-seed-by-50/
|
||||
|
||||
The fork consists of about 30 patches
|
||||
|
||||
ff2210b3 build: Add support for ARM.
|
||||
f8c8caaf ARM: allow fake asm in functions.
|
||||
d9ecdebc bootstrappable: ARM: Force eabi header.
|
||||
82b822c3 bootstrappable: HAVE_LONG_LONG, part 3.
|
||||
77ae03e8 bootstrappable: ARM: HAVE_FLOAT?
|
||||
82678555 bootstrappable: ARM: generate __memcpy, __memmove, __memset.
|
||||
0688c1f5 bootstrappable: ARM: HAVE_SETJMP.
|
||||
35c9c246 bootstrappable: HAVE_LONG_LONG_STUB.
|
||||
bdec98dd bootstrappable: HAVE_LONG_LONG, part 2.
|
||||
2556e105 bootstrappable: ARM: HAVE_FLOAT.
|
||||
fcb48635 bootstrappable: ARM: Avoid ternary.
|
||||
d0608d0d bootstrappable: ARM: Avoid ternary in argument.
|
||||
f7e98b52 bootstrappable: ARM: HAVE_FLOAT.
|
||||
e23023ec bootstrappable: HAVE_FLOAT, part 2.
|
||||
907479d7 bootstrappable: Avoid function modulo.
|
||||
33403a40 bootstrappable: Avoid using __clear_cache.
|
||||
94fa1710 bootstrappable: Use tmp initialization instead of for struct assigment.
|
||||
35ccd609 bootstrappable: Support libtcc1-mes.a.
|
||||
cee58e09 build: Support building from bootstrap-mes.
|
||||
39de3568 bootstrappable: Force static link.
|
||||
2b6271d1 bootstrappable: Work around MesCC bug.
|
||||
379c62d6 bootstrappable: add tcc.h include guards to include location.
|
||||
6ae9aa40 bootstrappable: Skip tidy_section_headers.
|
||||
a130ce17 bootstrappable: HAVE_FLOAT.
|
||||
de906df4 bootstrappable: HAVE_BITFIELD.
|
||||
540ba0b4 bootstrappable: HAVE_LONG_LONG.
|
||||
306f6779 bootstrappable: Work around Nyacc-0.80.42 bug.
|
||||
9c97705c build: bootstrap build scripts.
|
||||
584478fc bootstrappable: Remove non-free grep test.
|
||||
|
||||
that work around bugs and missing C language features in MesCC. Only
|
||||
three of these are really interesting: the HAVE_* patches that allow
|
||||
for stepwise introduction of bitfields, doubles/floats and long longs.
|
||||
|
||||
In time, I hope we can remove the need for this fork; either by
|
||||
upstreaming some bootstrappable work or else by maturing MesCC.
|
||||
|
||||
At the time of writing, mainline (non-bootstrappable) tinycc lives
|
||||
here
|
||||
|
||||
https://repo.or.cz/tinycc.git
|
||||
https://lists.nongnu.org/mailman/listinfo/tinycc-devel
|
||||
|
||||
--
|
||||
janneke
|
||||
|
||||
|
||||
Tiny C Compiler - C Scripting Everywhere - The Smallest ANSI C compiler
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -70,7 +70,6 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
|||
uint8_t *clobber_regs,
|
||||
int out_reg)
|
||||
{
|
||||
asm_error();
|
||||
}
|
||||
|
||||
ST_FUNC void asm_compute_constraints(ASMOperand *operands,
|
||||
|
@ -78,7 +77,6 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
|
|||
const uint8_t *clobber_regs,
|
||||
int *pout_reg)
|
||||
{
|
||||
asm_error();
|
||||
}
|
||||
|
||||
ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
|
||||
|
|
67
arm-gen.c
67
arm-gen.c
|
@ -636,7 +636,14 @@ void load(int r, SValue *sv)
|
|||
} else if (v < VT_CONST) {
|
||||
if(is_float(ft))
|
||||
#ifdef TCC_ARM_VFP
|
||||
#if !BOOTSTRAP
|
||||
o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */
|
||||
#else
|
||||
{
|
||||
int t = 0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft);
|
||||
o(t); /* fcpyX */
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
o(0xEE008180|(fpr(r)<<12)|fpr(v));
|
||||
#endif
|
||||
|
@ -749,7 +756,12 @@ static void gcall_or_jmp(int is_jmp)
|
|||
greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
|
||||
} else
|
||||
put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0);
|
||||
#if !BOOTSTRAP
|
||||
o(x|(is_jmp?0xE0000000:0xE1000000));
|
||||
#else
|
||||
x |= (is_jmp?0xE0000000:0xE1000000);
|
||||
o(x);
|
||||
#endif
|
||||
} else {
|
||||
if(!is_jmp)
|
||||
o(0xE28FE004); // add lr,pc,#4
|
||||
|
@ -804,7 +816,11 @@ struct avail_regs {
|
|||
int first_free_reg; /* next free register in the sequence, hole excluded */
|
||||
};
|
||||
|
||||
#if !BOOTSTRAP
|
||||
#define AVAIL_REGS_INITIALIZER (struct avail_regs) { { 0, 0, 0}, 0, 0, 0 }
|
||||
#else
|
||||
#define AVAIL_REGS_INITIALIZER {0}
|
||||
#endif
|
||||
|
||||
/* Find suitable registers for a VFP Co-Processor Register Candidate (VFP CPRC
|
||||
param) according to the rules described in the procedure call standard for
|
||||
|
@ -959,6 +975,7 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
|
|||
*todo = 0;
|
||||
plan->pplans = tcc_malloc(nb_args * sizeof(*plan->pplans));
|
||||
memset(plan->clsplans, 0, sizeof(plan->clsplans));
|
||||
|
||||
for(i = nb_args; i-- ;) {
|
||||
int j, start_vfpreg = 0;
|
||||
CType type = vtop[-i].type;
|
||||
|
@ -981,7 +998,12 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
|
|||
start_vfpreg = assign_vfpreg(&avregs, align, size);
|
||||
end_vfpreg = start_vfpreg + ((size - 1) >> 2);
|
||||
if (start_vfpreg >= 0) {
|
||||
#if !BOOTSTRAP
|
||||
pplan = (struct param_plan) {start_vfpreg, end_vfpreg, &vtop[-i]};
|
||||
#else
|
||||
struct param_plan tmp = {start_vfpreg, end_vfpreg, &vtop[-i]};
|
||||
pplan = tmp;
|
||||
#endif
|
||||
if (is_hfa)
|
||||
add_param_plan(plan, pplan, VFP_STRUCT_CLASS);
|
||||
else
|
||||
|
@ -998,7 +1020,14 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
|
|||
* CORE_STRUCT_CLASS or the first of STACK_CLASS. */
|
||||
for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
|
||||
*todo|=(1<<j);
|
||||
#if !BOOTSTRAP
|
||||
pplan = (struct param_plan) {ncrn, j, &vtop[-i]};
|
||||
#else
|
||||
{
|
||||
struct param_plan tmp = {ncrn, j, &vtop[-i]};
|
||||
pplan = tmp;
|
||||
}
|
||||
#endif
|
||||
add_param_plan(plan, pplan, CORE_STRUCT_CLASS);
|
||||
ncrn += size/4;
|
||||
if (ncrn > 4)
|
||||
|
@ -1017,7 +1046,12 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
|
|||
if (ncrn == 4)
|
||||
break;
|
||||
}
|
||||
#if !BOOTSTRAP
|
||||
pplan = (struct param_plan) {ncrn, ncrn, &vtop[-i]};
|
||||
#else
|
||||
struct param_plan tmp = {ncrn, ncrn, &vtop[-i]};
|
||||
pplan = tmp;
|
||||
#endif
|
||||
ncrn++;
|
||||
if (is_long)
|
||||
pplan.end = ncrn++;
|
||||
|
@ -1026,7 +1060,14 @@ static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
|
|||
}
|
||||
}
|
||||
nsaa = (nsaa + (align - 1)) & ~(align - 1);
|
||||
#if !BOOTSTRAP
|
||||
pplan = (struct param_plan) {nsaa, nsaa + size, &vtop[-i]};
|
||||
#else
|
||||
{
|
||||
struct param_plan tmp = {nsaa, nsaa + size, &vtop[-i]};
|
||||
pplan = tmp;
|
||||
}
|
||||
#endif
|
||||
add_param_plan(plan, pplan, STACK_CLASS);
|
||||
nsaa += size; /* size already rounded up before */
|
||||
}
|
||||
|
@ -1439,7 +1480,12 @@ int gtst(int inv, int t)
|
|||
if (nocode_wanted) {
|
||||
;
|
||||
} else if (v == VT_CMP) {
|
||||
#if !BOOTSTRAP
|
||||
op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
|
||||
#else
|
||||
int tmp_arg = inv?negcc(vtop->c.i):vtop->c.i;
|
||||
op=mapcc(tmp_arg);
|
||||
#endif
|
||||
op|=encbranch(r,t,1);
|
||||
o(op);
|
||||
t=r;
|
||||
|
@ -1643,6 +1689,7 @@ done:
|
|||
#ifdef TCC_ARM_VFP
|
||||
static int is_zero(int i)
|
||||
{
|
||||
#if HAVE_FLOAT
|
||||
if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
|
||||
return 0;
|
||||
if (vtop[i].type.t == VT_FLOAT)
|
||||
|
@ -1650,6 +1697,9 @@ static int is_zero(int i)
|
|||
else if (vtop[i].type.t == VT_DOUBLE)
|
||||
return (vtop[i].c.d == 0.0);
|
||||
return (vtop[i].c.ld == 0.l);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* generate a floating point operation 'v = t1 op t2' instruction. The
|
||||
|
@ -1746,6 +1796,7 @@ void gen_opf(int op)
|
|||
#else
|
||||
static uint32_t is_fconst()
|
||||
{
|
||||
#if HAVE_FLOAT
|
||||
long double f;
|
||||
uint32_t r;
|
||||
if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
|
||||
|
@ -1779,6 +1830,7 @@ static uint32_t is_fconst()
|
|||
return r|6;
|
||||
if(f==10.0)
|
||||
return r|7;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1965,7 +2017,12 @@ ST_FUNC void gen_cvt_itof1(int t)
|
|||
r2|=r2<<12;
|
||||
if(!(vtop->type.t & VT_UNSIGNED))
|
||||
r2|=0x80; /* fuitoX -> fsituX */
|
||||
#if !BOOTSTRAP
|
||||
o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
|
||||
#else
|
||||
int x = 0xEEB80A40|r2|T2CPR(t);
|
||||
o(x); /* fYitoX*/
|
||||
#endif
|
||||
#else
|
||||
r2=fpr(vtop->r=get_reg(RC_FLOAT));
|
||||
if((t & VT_BTYPE) != VT_FLOAT)
|
||||
|
@ -2041,7 +2098,12 @@ void gen_cvt_ftoi(int t)
|
|||
#ifdef TCC_ARM_VFP
|
||||
r=vfpr(gv(RC_FLOAT));
|
||||
u=u?0:0x10000;
|
||||
#if !BOOTSTRAP
|
||||
o(0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
|
||||
#else
|
||||
int x =0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u;
|
||||
o(x); /* ftoXizY */
|
||||
#endif
|
||||
r2=intr(vtop->r=get_reg(RC_INT));
|
||||
o(0xEE100A10|(r<<16)|(r2<<12));
|
||||
return;
|
||||
|
@ -2095,7 +2157,12 @@ void gen_cvt_ftof(int t)
|
|||
#ifdef TCC_ARM_VFP
|
||||
if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
|
||||
uint32_t r = vfpr(gv(RC_FLOAT));
|
||||
#if !BOOTSTRAP
|
||||
o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));
|
||||
#else
|
||||
int x = 0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t);
|
||||
o(x);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
/* all we have to do on i386 and FPA ARM is to put the float in a register */
|
||||
|
|
|
@ -0,0 +1,264 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$V" = 1 -o "$V" = 2 ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
arch=${arch-$(uname -m)}
|
||||
case $arch in
|
||||
aarch*)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
arm*|aarch*)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-unknown-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
riscv*)
|
||||
cpu=riscv64
|
||||
mes_cpu=riscv64
|
||||
tcc_cpu=riscv64
|
||||
triplet=riscv64-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
*)
|
||||
cpu=x86
|
||||
mes_cpu=x86
|
||||
tcc_cpu=i386
|
||||
triplet=i686-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$TCC" = ./mes-tcc ]; then
|
||||
program_prefix=${program_prefix-boot0-}
|
||||
elif [ "$TCC" = ./boot0-tcc ]; then
|
||||
program_prefix=${program_prefix-boot1-}
|
||||
elif [ "$TCC" = ./boot1-tcc ]; then
|
||||
program_prefix=${program_prefix-boot2-}
|
||||
elif [ "$TCC" = ./boot2-tcc ]; then
|
||||
program_prefix=${program_prefix-boot3-}
|
||||
elif [ "$TCC" = ./boot3-tcc ]; then
|
||||
program_prefix=${program_prefix-boot4-}
|
||||
elif [ "$TCC" = ./boot4-tcc ]; then
|
||||
program_prefix=${program_prefix-boot5-}
|
||||
elif [ "$TCC" = ./boot5-tcc ]; then
|
||||
program_prefix=${program_prefix-boot6-}
|
||||
elif [ "$TCC" = ./boot6-tcc ]; then
|
||||
program_prefix=${program_prefix-boot7-}
|
||||
elif [ "$TCC" = ./boot7-tcc ]; then
|
||||
program_prefix=${program_prefix-boot8-}
|
||||
elif [ "$TCC" = ./boot8-tcc ]; then
|
||||
program_prefix=${program_prefix-boot9-}
|
||||
elif [ "$TCC" = ./gcc-tcc ]; then
|
||||
program_prefix=${program_prefix-boot0-}
|
||||
elif [ "$TCC" = ${cross_prefix}gcc ]; then
|
||||
program_prefix=${program_prefix-boot0-}
|
||||
elif [ "$TCC" = ./${cross_prefix}tcc ]; then
|
||||
program_prefix=${program_prefix-boot0-}
|
||||
else
|
||||
program_prefix=${program_prefix-foo-}
|
||||
fi
|
||||
|
||||
unset C_INCLUDE_PATH LIBRARY_PATH
|
||||
prefix=${prefix-/usr/local}
|
||||
mkdir -p $prefix
|
||||
absprefix=$(cd $prefix && pwd)
|
||||
GUIX=${GUIX-$(command -v guix||:)}
|
||||
MES_PREFIX=${MES_PREFIX-mes}
|
||||
MES_LIB=${MES_LIB-$MES_PREFIX/lib}
|
||||
C_INCLUDE_PATH=${C_INCLUDE_PATH-$MES_PREFIX/include}
|
||||
LIBRARY_PATH=${LIBRARY_PATH-..$MES_PREFIX/lib}
|
||||
interpreter=/lib/mes-loader
|
||||
|
||||
if [ "$program_prefix" = "boot0-" ]; then
|
||||
BOOT_CPPFLAGS_TCC="
|
||||
-D BOOTSTRAP=1
|
||||
"
|
||||
if $have_long_long; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_LONG_LONG_STUB=1"
|
||||
fi
|
||||
elif [ "$program_prefix" = "boot1-" ]; then
|
||||
BOOT_CPPFLAGS_TCC="
|
||||
-D BOOTSTRAP=1
|
||||
-D HAVE_BITFIELD=1
|
||||
"
|
||||
if $have_long_long; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_LONG_LONG=1"
|
||||
fi
|
||||
elif [ "$program_prefix" = "boot2-" ]; then
|
||||
BOOT_CPPFLAGS_TCC="
|
||||
-D BOOTSTRAP=1
|
||||
-D HAVE_BITFIELD=1
|
||||
"
|
||||
if $have_float; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_FLOAT_STUB=1"
|
||||
fi
|
||||
if $have_long_long; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_LONG_LONG=1"
|
||||
fi
|
||||
elif [ "$program_prefix" = "boot3-" ]; then
|
||||
BOOT_CPPFLAGS_TCC="
|
||||
-D BOOTSTRAP=1
|
||||
-D HAVE_BITFIELD=1
|
||||
"
|
||||
if $have_float; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_FLOAT=1"
|
||||
fi
|
||||
if $have_long_long; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_LONG_LONG=1"
|
||||
fi
|
||||
else
|
||||
BOOT_CPPFLAGS_TCC="
|
||||
-D BOOTSTRAP=1
|
||||
-D HAVE_BITFIELD=1
|
||||
"
|
||||
if $have_float; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_FLOAT=1"
|
||||
fi
|
||||
if $have_long_long; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_LONG_LONG=1"
|
||||
fi
|
||||
fi
|
||||
|
||||
if $have_setjmp; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_SETJMP=1"
|
||||
fi
|
||||
|
||||
if test "$mes_cpu" = x86; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_I386=1"
|
||||
elif test "$mes_cpu" = arm; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_ARM=1 -D TCC_ARM_VFP=1 -D CONFIG_TCC_LIBTCC1_MES=1"
|
||||
elif test "$mes_cpu" = x86_64; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_SETJMP=1"
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_X86_64=1"
|
||||
elif test "$mes_cpu" = riscv64; then
|
||||
BOOT_CPPFLAGS_TCC="$BOOT_CPPFLAGS_TCC -D HAVE_SETJMP=1"
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_RISC64=1"
|
||||
else
|
||||
echo "cpu not supported: $mes_cpu"
|
||||
fi
|
||||
|
||||
CPPFLAGS_TCC="
|
||||
-I .
|
||||
-I $MES_PREFIX/lib
|
||||
-I $MES_PREFIX/include
|
||||
$CPP_TARGET_FLAG
|
||||
-D inline=
|
||||
-D CONFIG_TCCDIR=\"$prefix/lib/tcc\"
|
||||
-D CONFIG_TCC_CRTPREFIX=\"$prefix/lib:"{B}"/lib:.\"
|
||||
-D CONFIG_TCC_ELFINTERP=\"$interpreter\"
|
||||
-D CONFIG_TCC_LIBPATHS=\"$prefix/lib:"{B}"/lib:.\"
|
||||
-D CONFIG_TCC_SYSINCLUDEPATHS=\"$MES_PREFIX/include:$prefix/include:"{B}"/include\"
|
||||
-D TCC_LIBGCC=\"$prefix/lib/libc.a\"
|
||||
-D TCC_LIBTCC1_MES=\"libtcc1-mes.a\"
|
||||
-D CONFIG_TCCBOOT=1
|
||||
-D CONFIG_TCC_STATIC=1
|
||||
-D CONFIG_USE_LIBGCC=1
|
||||
-D TCC_MES_LIBC=1
|
||||
"
|
||||
|
||||
if $ONE_SOURCE; then
|
||||
CPPFLAGS_TCC="$CPPFLAGS_TCC -D ONE_SOURCE=1"
|
||||
fi
|
||||
|
||||
if $ONE_SOURCE; then
|
||||
files="tcc.c"
|
||||
else
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC tccpp.c
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC tccgen.c
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC tccelf.c
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC tccrun.c
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC ${tcc_cpu}-gen.c
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC ${tcc_cpu}-link.c
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC ${tcc_cpu}-asm.c
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC tccasm.c
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC libtcc.c
|
||||
$TCC -g -v -c $BOOT_CPPFLAGS_TCC $CPPFLAGS_TCC tcc.c
|
||||
files="
|
||||
tccpp.o
|
||||
tccgen.o
|
||||
tccelf.o
|
||||
tccrun.o
|
||||
${tcc_cpu}-gen.o
|
||||
${tcc_cpu}-link.o
|
||||
${tcc_cpu}-asm.o
|
||||
tccasm.o
|
||||
libtcc.o
|
||||
tcc.o
|
||||
"
|
||||
fi
|
||||
|
||||
echo $TCC \
|
||||
-g \
|
||||
-v \
|
||||
-static \
|
||||
-o ${program_prefix}tcc \
|
||||
$BOOT_CPPFLAGS_TCC \
|
||||
$CPPFLAGS_TCC \
|
||||
-L . \
|
||||
$files
|
||||
|
||||
$TCC \
|
||||
-g \
|
||||
-v \
|
||||
-static \
|
||||
-o ${program_prefix}tcc \
|
||||
$BOOT_CPPFLAGS_TCC \
|
||||
$CPPFLAGS_TCC \
|
||||
-L . \
|
||||
$files
|
||||
|
||||
if $REBUILD_LIBC; then
|
||||
for i in 1 i n; do
|
||||
cp -f $MES_LIB/crt$i.c .
|
||||
./${program_prefix}tcc -c -g -o ${program_prefix}crt$i.o crt$i.c
|
||||
cp -f ${program_prefix}crt$i.o crt$i.o
|
||||
done
|
||||
|
||||
rm -f libtcc1.a
|
||||
./${program_prefix}tcc -c -g $CPP_TARGET_FLAG -D HAVE_FLOAT=1 -o libtcc1.o $MES_LIB/libtcc1.c
|
||||
./${program_prefix}tcc -ar rc libtcc1.a libtcc1.o
|
||||
|
||||
if [ $mes_cpu = arm ]; then
|
||||
./${program_prefix}tcc -c -g $BOOT_CPPFLAGS lib/armeabi.c
|
||||
|
||||
./${program_prefix}tcc -c -g $CPP_TARGET_FLAG $BOOT_CPPFLAGS_TCC -o libtcc1-tcc.o lib/libtcc1.c
|
||||
./${program_prefix}tcc -ar rc libtcc1-tcc.a libtcc1-tcc.o armeabi.o
|
||||
|
||||
# BOOTSTRAP: => Bus error
|
||||
##./${program_prefix}tcc -c -g $CPP_TARGET_FLAG $BOOT_CPPFLAGS_TCC -o libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
##./${program_prefix}tcc -c -g $CPP_TARGET_FLAG -D BOOTSTRAP=1 -D HAVE_FLOAT=1 -D HAVE_LONG_LONG=1 -o libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
./${program_prefix}tcc -c -g $CPP_TARGET_FLAG -D HAVE_FLOAT=1 -D HAVE_LONG_LONG=1 -o libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
./${program_prefix}tcc -ar rc libtcc1-mes.a libtcc1-mes.o armeabi.o
|
||||
|
||||
./${program_prefix}tcc -c -g $CPP_TARGET_FLAG $BOOT_CPPFLAGS_TCC -o libtcc1.o lib/libtcc1.c
|
||||
./${program_prefix}tcc -ar rc libtcc1.a libtcc1.o armeabi.o
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
if [ $mes_cpu = riscv64 ]; then
|
||||
./${program_prefix}tcc -c -g $BOOT_CPPFLAGS lib/lib-arm64.c
|
||||
|
||||
./${program_prefix}tcc -c -g $CPP_TARGET_FLAG $BOOT_CPPFLAGS_TCC -o libtcc1-tcc.o lib/libtcc1.c
|
||||
./${program_prefix}tcc -ar rc libtcc1-tcc.a libtcc1-tcc.o lib-arm64.o
|
||||
|
||||
./${program_prefix}tcc -c -g $CPP_TARGET_FLAG -D HAVE_FLOAT=1 -D HAVE_LONG_LONG=1 -o libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
./${program_prefix}tcc -ar rc libtcc1-mes.a libtcc1-mes.o lib-arm64.o
|
||||
|
||||
./${program_prefix}tcc -c -g $CPP_TARGET_FLAG $BOOT_CPPFLAGS_TCC -o libtcc1.o lib/libtcc1.c
|
||||
./${program_prefix}tcc -ar rc libtcc1.a libtcc1.o lib-arm64.o
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
|
||||
cp -f libtcc1.a $prefix/lib/tcc
|
||||
fi
|
||||
|
||||
echo "boot.sh: done"
|
|
@ -0,0 +1,292 @@
|
|||
#! /bin/sh
|
||||
set -e
|
||||
|
||||
if test "$V" = 1 -o "$V" = 2; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
MESCC=${MESCC-$(command -v mescc)}
|
||||
|
||||
if test "$V" = 2; then
|
||||
sh $MESCC --help
|
||||
fi
|
||||
|
||||
host=${host-$($MESCC -dumpmachine 2>/dev/null)}
|
||||
if test -z "$host$host_type"; then
|
||||
mes_cpu=${arch-$(get_machine || uname -m)}
|
||||
else
|
||||
mes_cpu=${host%%-*}
|
||||
fi
|
||||
case "$mes_cpu" in
|
||||
i386|i486|i586|i686|x86)
|
||||
mes_cpu=x86
|
||||
tcc_cpu=i386
|
||||
have_float=${have_float-true}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-true}
|
||||
;;
|
||||
armv4|armv7l|arm)
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
have_float=${have_float-true}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-false}
|
||||
;;
|
||||
riscv*)
|
||||
cpu=riscv64
|
||||
mes_cpu=riscv64
|
||||
tcc_cpu=riscv64
|
||||
triplet=riscv64-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
amd64)
|
||||
tcc_cpu=x86_64
|
||||
mes_cpu=x86_64
|
||||
have_float=${have_float-true}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-true}
|
||||
;;
|
||||
esac
|
||||
case "$host" in
|
||||
*linux-gnu|*linux)
|
||||
mes_kernel=linux;;
|
||||
*gnu)
|
||||
mes_kernel=gnu;;
|
||||
*)
|
||||
mes_kernel=linux;;
|
||||
esac
|
||||
export mes_cpu
|
||||
export tcc_cpu
|
||||
export have_float
|
||||
export have_long_long
|
||||
export have_setjmp
|
||||
|
||||
prefix=${prefix-/usr/local}
|
||||
MES_PREFIX=${MES_PREFIX-mes}
|
||||
MES_STACK=${MES_STACK-10000000}
|
||||
export MES_STACK
|
||||
interpreter=${interpreter-/mes/loader}
|
||||
MES_LIB=${MES_LIB-$MES_PREFIX/lib}
|
||||
MES_SOURCE=${MES_SOURCE-mes-source}
|
||||
#MES_LIB=$MES_SOURCE/gcc-lib/${mes_cpu}-mes
|
||||
export MES_SOURCE
|
||||
export MES_PREFIX
|
||||
export MES_LIB
|
||||
|
||||
ONE_SOURCE=${ONE_SOURCE-false}
|
||||
export ONE_SOURCE
|
||||
|
||||
CPPFLAGS="
|
||||
-I $MES_PREFIX/lib
|
||||
-I $MES_PREFIX/include
|
||||
-D BOOTSTRAP=1
|
||||
"
|
||||
|
||||
if test "$mes_cpu" = x86; then
|
||||
CPP_TARGET_FLAG=" -D TCC_TARGET_I386=1"
|
||||
elif test "$mes_cpu" = arm; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_ARM=1 -D TCC_ARM_VFP=1 -D CONFIG_TCC_LIBTCC1_MES=1"
|
||||
elif test "$mes_cpu" = x86_64; then
|
||||
CPP_TARGET_FLAG=" -D TCC_TARGET_X86_64=1"
|
||||
elif test "$mes_cpu" = riscv64; then
|
||||
CPP_TARGET_FLAG=" -D TCC_TARGET_RISCV64=1 -D HAVE_LONG_LONG=1"
|
||||
else
|
||||
echo "cpu not supported: $mes_cpu"
|
||||
fi
|
||||
|
||||
CPPFLAGS_TCC="$CPPFLAGS
|
||||
-I .
|
||||
$CPP_TARGET_FLAG
|
||||
-D inline=
|
||||
-D CONFIG_TCCDIR=\"$prefix/lib/tcc\"
|
||||
-D CONFIG_TCC_CRTPREFIX=\"$prefix/lib:"{B}"/lib:.\"
|
||||
-D CONFIG_TCC_ELFINTERP=\"$interpreter\"
|
||||
-D CONFIG_TCC_LIBPATHS=\"$prefix/lib:"{B}"/lib:.\"
|
||||
-D CONFIG_TCC_SYSINCLUDEPATHS=\"$MES_PREFIX/include:$prefix/include:"{B}"/include\"
|
||||
-D TCC_LIBGCC=\"$prefix/lib/libc.a\"
|
||||
-D TCC_LIBTCC1_MES=\"libtcc1-mes.a\"
|
||||
-D CONFIG_TCCBOOT=1
|
||||
-D CONFIG_TCC_STATIC=1
|
||||
-D CONFIG_USE_LIBGCC=1
|
||||
-D TCC_MES_LIBC=1
|
||||
"
|
||||
|
||||
if $ONE_SOURCE; then
|
||||
files="tcc.s"
|
||||
CPPFLAGS_TCC="$CPPFLAGS_TCC -D ONE_SOURCE=1"
|
||||
else
|
||||
files="tccpp.s tccgen.s tccelf.s tccrun.s ${tcc_cpu}-gen.s ${tcc_cpu}-link.s ${tcc_cpu}-asm.s tccasm.s libtcc.s tcc.s"
|
||||
fi
|
||||
|
||||
CFLAGS=
|
||||
if test "$V" = 1; then
|
||||
CFLAGS="$CFLAGS -v"
|
||||
elif test "$V" = 2; then
|
||||
CFLAGS="$CFLAGS -v -v"
|
||||
fi
|
||||
|
||||
for f in $files; do
|
||||
i=$(basename $f .s)
|
||||
[ -z "$V" ] && echo " CC $i.c"
|
||||
sh $MESCC \
|
||||
-S \
|
||||
-o $f \
|
||||
$CPPFLAGS_TCC \
|
||||
$CFLAGS \
|
||||
$i.c
|
||||
done
|
||||
|
||||
[ -z "$V" ] && echo " CCLD mes-tcc"
|
||||
sh $MESCC $verbose -o mes-tcc -L $MES_SOURCE/mescc-lib -L $MES_SOURCE/lib $files -l c+tcc
|
||||
|
||||
CC="./mes-tcc"
|
||||
AR="./mes-tcc -ar"
|
||||
CPPFLAGS="
|
||||
-I $MES_PREFIX/include
|
||||
-I $MES_PREFIX/include/$mes_kernel/$mes_cpu
|
||||
-I $MES_PREFIX/lib
|
||||
-D BOOTSTRAP=1
|
||||
"
|
||||
CFLAGS=
|
||||
|
||||
REBUILD_LIBC=${REBUILD_LIBC-true}
|
||||
export REBUILD_LIBC
|
||||
|
||||
mkdir -p $prefix/lib/tcc
|
||||
if $REBUILD_LIBC; then
|
||||
for i in 1 i n; do
|
||||
rm -f crt$i.o;
|
||||
cp -f $MES_LIB/crt$i.c .
|
||||
$CC $CPPFLAGS $CFLAGS -static -nostdlib -nostdinc -c crt$i.c
|
||||
done
|
||||
|
||||
rm -f libc.a
|
||||
cp -f $MES_LIB/libc+gnu.c libc.c
|
||||
$CC -c $CPPFLAGS $CFLAGS libc.c
|
||||
$AR cr libc.a libc.o
|
||||
|
||||
rm -f libtcc1.a
|
||||
cp -f $MES_LIB/libtcc1.c .
|
||||
$CC -c $CPPFLAGS $CFLAGS libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o
|
||||
|
||||
if [ $mes_cpu = arm ]; then
|
||||
$CC -c $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG lib/armeabi.c
|
||||
$CC -c $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG lib/libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o armeabi.o
|
||||
|
||||
$CC -c $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG -o libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
# $AR cr libtcc1-mes.a libtcc1-mes.o armeabi.o
|
||||
$AR cr libtcc1-mes.a libtcc1-mes.o
|
||||
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
if [ $mes_cpu = riscv64]; then
|
||||
$CC -c $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG lib/lib-arm64.c
|
||||
$CC -c $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG lib/libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o lib-arm64.o
|
||||
|
||||
$CC -c $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG -o libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
# $AR cr libtcc1-mes.a libtcc1-mes.o armeabi.o
|
||||
$AR cr libtcc1-mes.a libtcc1-mes.o
|
||||
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
|
||||
rm -f libgetopt.a
|
||||
cp -f $MES_LIB/libgetopt.c .
|
||||
$CC -c $CPPFLAGS $CFLAGS libgetopt.c
|
||||
$AR cr libgetopt.a libgetopt.o
|
||||
else
|
||||
cp -f $MES_LIB/crt1.o .
|
||||
cp -f $MES_LIB/crti.o .
|
||||
cp -f $MES_LIB/crtn.o .
|
||||
cp -f $MES_LIB/libc+gnu.a .
|
||||
cp -f $MES_LIB/libtcc1.a .
|
||||
cp -f $MES_LIB/libgetopt.a .
|
||||
|
||||
if [ $mes_cpu = arm ]; then
|
||||
$CC -c $CPPFLAGS $CFLAGS $MES_LIB/libtcc1.c
|
||||
$CC -c $CPPFLAGS $CFLAGS lib/armeabi.c
|
||||
$AR cr libtcc1.a libtcc1.o armeabi.o
|
||||
fi
|
||||
fi
|
||||
|
||||
cp -f libc.a $prefix/lib
|
||||
cp -f libtcc1.a $prefix/lib/tcc
|
||||
cp -f libgetopt.a $prefix/lib
|
||||
|
||||
export mes_cpu
|
||||
export prefix
|
||||
export CPPFLAGS
|
||||
|
||||
TCC=./mes-tcc sh boot.sh
|
||||
TCC=./boot0-tcc sh boot.sh
|
||||
TCC=./boot1-tcc sh boot.sh
|
||||
TCC=./boot2-tcc sh boot.sh
|
||||
TCC=./boot3-tcc sh boot.sh
|
||||
TCC=./boot4-tcc sh boot.sh
|
||||
TCC=./boot5-tcc sh boot.sh
|
||||
if cmp --help; then
|
||||
cmp boot5-tcc boot6-tcc
|
||||
fi
|
||||
cp -f boot5-tcc tcc
|
||||
|
||||
CC=./tcc
|
||||
AR='./tcc -ar'
|
||||
if true; then
|
||||
for i in 1 i n; do
|
||||
rm -f crt$i.o;
|
||||
cp -f $MES_LIB/crt$i.c .
|
||||
$CC -c -g $CPPFLAGS $CFLAGS -static -nostdlib -nostdinc crt$i.c
|
||||
done
|
||||
|
||||
rm -f libc.a
|
||||
$CC -c -g $CPPFLAGS $CFLAGS libc.c
|
||||
$AR cr libc.a libc.o
|
||||
|
||||
rm -f libtcc1.a
|
||||
$CC -c -g $CPPFLAGS $CPP_TARGET_FLAG $CFLAGS lib/libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o
|
||||
|
||||
if [ $mes_cpu = arm ]; then
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG lib/armeabi.c
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG -o libtcc1-tcc.o lib/libtcc1.c
|
||||
$AR rc libtcc1-tcc.a libtcc1-tcc.o armeabi.o
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS -D HAVE_FLOAT=1 -D HAVE_LONG_LONG=1 libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
$AR cr libtcc1-mes.a libtcc1-mes.o armeabi.o
|
||||
|
||||
$CC -c -g $CPP_TARGET_FLAG $CFLAGS -o libtcc1.o lib/libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o armeabi.o
|
||||
|
||||
cp -f libtcc1-tcc.a $prefix/lib/tcc
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
if [ $mes_cpu = riscv64 ]; then
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG lib/lib-arm64.c
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG -o libtcc1-tcc.o lib/libtcc1.c
|
||||
$AR rc libtcc1-tcc.a libtcc1-tcc.o lib-arm64.o
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS -D HAVE_FLOAT=1 -D HAVE_LONG_LONG=1 libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
$AR cr libtcc1-mes.a libtcc1-mes.o lib-arm64.o
|
||||
|
||||
$CC -c -g $CPP_TARGET_FLAG $CFLAGS -o libtcc1.o lib/libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o lib-arm64.o
|
||||
|
||||
cp -f libtcc1-tcc.a $prefix/lib/tcc
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
|
||||
rm -f libgetopt.a
|
||||
$CC -c -g $CPPFLAGS $CFLAGS libgetopt.c
|
||||
$AR cr libgetopt.a libgetopt.o
|
||||
|
||||
cp -f libc.a $prefix/lib
|
||||
cp -f libtcc1.a $prefix/lib/tcc
|
||||
cp -f libgetopt.a $prefix/lib
|
||||
fi
|
||||
|
||||
echo "bootstrap.sh: done"
|
|
@ -0,0 +1,303 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if test "$V" = 1 -o "$V" = 2; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
aarch*)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
have_float=${have_float-false}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-false}
|
||||
;;
|
||||
arm*|aarch)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-unknown-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
have_float=${have_float-false}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-false}
|
||||
;;
|
||||
*)
|
||||
cpu=x86
|
||||
mes_cpu=x86
|
||||
tcc_cpu=i386
|
||||
triplet=i686-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
have_float=${have_float-true}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-true}
|
||||
;;
|
||||
esac
|
||||
case "$host" in
|
||||
*linux-gnu|*linux)
|
||||
mes_kernel=linux;;
|
||||
*gnu)
|
||||
mes_kernel=gnu;;
|
||||
*)
|
||||
mes_kernel=linux;;
|
||||
esac
|
||||
export cpu
|
||||
export cross_prefix
|
||||
export mes_cpu
|
||||
export tcc_cpu
|
||||
export triplet
|
||||
export have_float
|
||||
export have_long_long
|
||||
export have_setjmp
|
||||
|
||||
prefix=${prefix-usr}
|
||||
export prefix
|
||||
MES_PREFIX=${MES_PREFIX-mes-source}
|
||||
MES_SOURCE=${MES_SOURCE-mes-source}
|
||||
MES_LIB=${MES_LIB-$MES_PREFIX/lib}
|
||||
MES_LIB=$MES_SOURCE/gcc-lib/${mes_cpu}-mes
|
||||
|
||||
ONE_SOURCE=${ONE_SOURCE-false}
|
||||
|
||||
export V
|
||||
export MESCC
|
||||
export MES_DEBUG
|
||||
export MES_PREFIX
|
||||
export MES_LIB
|
||||
export MES_SOURCE
|
||||
export ONE_SOURCE
|
||||
export REBUILD_LIBC
|
||||
|
||||
CC=${CC-${cross_prefix}gcc}
|
||||
CPPFLAGS="
|
||||
-I $MES_PREFIX/include
|
||||
-I $MES_PREFIX/include/$mes_kernel/$mes_cpu
|
||||
-I $MES_PREFIX/lib
|
||||
-D BOOTSTRAP=1
|
||||
"
|
||||
|
||||
CFLAGS="
|
||||
-fpack-struct
|
||||
-nostdinc
|
||||
-nostdlib
|
||||
-fno-builtin
|
||||
"
|
||||
|
||||
if test "$mes_cpu" = x86; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_I386=1"
|
||||
elif test "$mes_cpu" = arm; then
|
||||
CFLAGS="$CFLAGS -marm"
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_ARM=1 -D TCC_ARM_VFP=1 -D CONFIG_TCC_LIBTCC1_MES=1"
|
||||
elif test "$mes_cpu" = x86_64; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_X86_64=1"
|
||||
else
|
||||
echo "cpu not supported: $mes_cpu"
|
||||
fi
|
||||
|
||||
rm -f mes
|
||||
ln -sf $MES_PREFIX mes
|
||||
|
||||
rm -f ${cross_prefix}tcc
|
||||
unset C_INCLUDE_PATH LIBRARY_PATH
|
||||
|
||||
$CC -c $CPPFLAGS $CFLAGS $MES_PREFIX/lib/linux/$mes_cpu-mes-gcc/crt1.c
|
||||
$CC -c $CPPFLAGS $CFLAGS $MES_PREFIX/lib/linux/$mes_cpu-mes-gcc/crti.c
|
||||
$CC -c $CPPFLAGS $CFLAGS $MES_PREFIX/lib/linux/$mes_cpu-mes-gcc/crtn.c
|
||||
|
||||
cp $MES_LIB/libc+tcc.a .
|
||||
cp $MES_LIB/libtcc1.a .
|
||||
cp $MES_LIB/libc+tcc.a libc.a
|
||||
|
||||
mkdir -p $prefix/lib
|
||||
absprefix=$(cd $prefix && pwd)
|
||||
|
||||
interpreter=/lib/mes-loader
|
||||
export interpreter
|
||||
|
||||
if $ONE_SOURCE; then
|
||||
CFLAGS="$CFLAGS
|
||||
--include=$MES_SOURCE/lib/linux/$cpu-mes-gcc/crt1.c
|
||||
-Wl,-Ttext-segment=0x1000000
|
||||
"
|
||||
else
|
||||
LDFLAGS="
|
||||
-L .
|
||||
--include=$MES_SOURCE/lib/linux/$cpu-mes-gcc/crt1.c
|
||||
-Wl,-Ttext-segment=0x1000000
|
||||
"
|
||||
fi
|
||||
|
||||
CPPFLAGS_TCC="$CPPFLAGS
|
||||
-I .
|
||||
$CPP_TARGET_FLAG
|
||||
-D inline=
|
||||
-D CONFIG_TCCDIR=\"$prefix/lib/tcc\"
|
||||
-D CONFIG_TCC_CRTPREFIX=\"$prefix/lib:"{B}"/lib:.\"
|
||||
-D CONFIG_TCC_ELFINTERP=\"$interpreter\"
|
||||
-D CONFIG_TCC_LIBPATHS=\"$prefix/lib:"{B}"/lib:.\"
|
||||
-D CONFIG_TCC_SYSINCLUDEPATHS=\"$MES_PREFIX/include:$prefix/include:"{B}"/include\"
|
||||
-D TCC_LIBGCC=\"$prefix/lib/libc.a\"
|
||||
-D TCC_LIBTCC1_MES=\"libtcc1-mes.a\"
|
||||
-D CONFIG_TCCBOOT=1
|
||||
-D CONFIG_TCC_STATIC=1
|
||||
-D CONFIG_USE_LIBGCC=1
|
||||
-D TCC_MES_LIBC=1
|
||||
"
|
||||
|
||||
if $ONE_SOURCE; then
|
||||
CPPFLAGS_TCC="$CPPFLAGS_TCC -D ONE_SOURCE=1"
|
||||
fi
|
||||
|
||||
if $ONE_SOURCE; then
|
||||
$CC -g -o ${cross_prefix}tcc \
|
||||
$CFLAGS \
|
||||
$CPPFLAGS_TCC \
|
||||
tcc.c \
|
||||
libtcc1.a \
|
||||
libc.a \
|
||||
-lgcc \
|
||||
libc.a
|
||||
else
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC tccpp.c
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC tccgen.c
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC tccelf.c
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC tccrun.c
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC ${tcc_cpu}-gen.c
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC ${tcc_cpu}-link.c
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC ${tcc_cpu}-asm.c
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC tccasm.c
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC libtcc.c
|
||||
$CC -g -c $CFLAGS $CPPFLAGS_TCC tcc.c
|
||||
files="
|
||||
tccpp.o
|
||||
tccgen.o
|
||||
tccelf.o
|
||||
tccrun.o
|
||||
${tcc_cpu}-gen.o
|
||||
${tcc_cpu}-link.o
|
||||
${tcc_cpu}-asm.o
|
||||
tccasm.o
|
||||
libtcc.o
|
||||
tcc.o
|
||||
"
|
||||
$CC \
|
||||
-g \
|
||||
$LDFLAGS \
|
||||
$CPPFLAGS_TCC \
|
||||
-o ${cross_prefix}tcc \
|
||||
$files \
|
||||
libtcc1.a \
|
||||
libc.a \
|
||||
-lgcc \
|
||||
libc.a
|
||||
fi
|
||||
|
||||
rm -rf ${cross_prefix}gcc-usr
|
||||
mkdir -p ${cross_prefix}gcc-usr
|
||||
cp *.a ${cross_prefix}gcc-usr
|
||||
cp *.o ${cross_prefix}gcc-usr
|
||||
|
||||
mkdir -p $prefix/lib/tcc
|
||||
cp -f libc.a $prefix/lib
|
||||
cp -f libtcc1.a $prefix/lib/tcc
|
||||
|
||||
rm -f armeabi.o
|
||||
cp libtcc1.a libtcc1-mes.a
|
||||
|
||||
# REBUILD_LIBC=true
|
||||
# TCC=$CC sh -x boot.sh
|
||||
# REBUILD_LIBC=true
|
||||
# TCC=./boot0-tcc sh boot.sh
|
||||
# TCC=./boot1-tcc sh boot.sh
|
||||
# TCC=./boot2-tcc sh boot.sh
|
||||
# TCC=./boot3-tcc sh boot.sh
|
||||
# TCC=./boot4-tcc sh boot.sh
|
||||
# TCC=./boot5-tcc sh boot.sh
|
||||
# TCC=./boot6-tcc sh boot.sh
|
||||
|
||||
# exit 22
|
||||
|
||||
rm -rf ${cross_prefix}gcc-boot
|
||||
mkdir -p ${cross_prefix}gcc-boot
|
||||
cp *.a ${cross_prefix}gcc-boot
|
||||
cp *.o ${cross_prefix}gcc-boot
|
||||
|
||||
CC="./${cross_prefix}tcc"
|
||||
AR="./${cross_prefix}tcc -ar"
|
||||
CFLAGS=
|
||||
|
||||
REBUILD_LIBC=${REBUILD_LIBC-true}
|
||||
|
||||
$CC -c $CPPFLAGS $CFLAGS $MES_PREFIX/lib/linux/$mes_cpu-mes-gcc/crt1.c
|
||||
$CC -c $CPPFLAGS $CFLAGS $MES_PREFIX/lib/linux/$mes_cpu-mes-gcc/crti.c
|
||||
$CC -c $CPPFLAGS $CFLAGS $MES_PREFIX/lib/linux/$mes_cpu-mes-gcc/crtn.c
|
||||
|
||||
cp $MES_LIB/libc+tcc.a .
|
||||
cp $MES_LIB/libtcc1.a .
|
||||
cp $MES_LIB/libc+tcc.a libc.a
|
||||
|
||||
mkdir -p $prefix/lib/tcc
|
||||
if $REBUILD_LIBC; then
|
||||
for i in 1 i n; do
|
||||
rm -f crt$i.o;
|
||||
cp -f $MES_LIB/crt$i.c .
|
||||
$CC $CPPFLAGS $CFLAGS -static -nostdlib -nostdinc -c crt$i.c
|
||||
done
|
||||
|
||||
rm -f libc.a
|
||||
cp -f $MES_LIB/libc+gnu.c libc.c
|
||||
$CC -c $CPPFLAGS $CFLAGS libc.c
|
||||
$AR cr libc.a libc.o
|
||||
|
||||
rm -f libtcc1.a
|
||||
cp -f $MES_LIB/libtcc1.c .
|
||||
$CC -c $CPPFLAGS $CPP_TARGET_FLAG $CFLAGS lib/libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o
|
||||
|
||||
if [ $mes_cpu = arm ]; then
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG lib/armeabi.c
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG -o libtcc1-tcc.o lib/libtcc1.c
|
||||
$AR rc libtcc1-tcc.a libtcc1-tcc.o armeabi.o
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS -D HAVE_FLOAT=1 -D HAVE_LONG_LONG=1 -o libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
$AR cr libtcc1-mes.a libtcc1-mes.o armeabi.o
|
||||
|
||||
$CC -c -g $CPP_TARGET_FLAG $CFLAGS -o libtcc1.o lib/libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o armeabi.o
|
||||
|
||||
cp -f libtcc1-tcc.a $prefix/lib/tcc
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
|
||||
rm -f libgetopt.a
|
||||
cp -f $MES_LIB/libgetopt.c .
|
||||
$CC -c $CPPFLAGS $CFLAGS libgetopt.c
|
||||
$AR cr libgetopt.a libgetopt.o
|
||||
else
|
||||
cp -f $MES_LIB/crt1.o .
|
||||
cp -f $MES_LIB/crti.o .
|
||||
cp -f $MES_LIB/crtn.o .
|
||||
cp -f $MES_LIB/libc+gnu.a libc.a
|
||||
cp -f $MES_LIB/libtcc1.a .
|
||||
cp -f $MES_LIB/libgetopt.a .
|
||||
|
||||
if [ $mes_cpu = arm ]; then
|
||||
cp -f $MES_LIB/libtcc1.a $MES_LIB/libtcc1-mes.a
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
fi
|
||||
|
||||
cp -f libc.a $prefix/lib
|
||||
cp -f libtcc1.a $prefix/lib/tcc
|
||||
|
||||
rm -rf ${cross_prefix}tcc-usr
|
||||
mkdir -p ${cross_prefix}tcc-usr
|
||||
cp *.a ${cross_prefix}tcc-usr
|
||||
cp *.o ${cross_prefix}tcc-usr
|
|
@ -0,0 +1,84 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
|
||||
CC=${CC-gcc}
|
||||
crt1=$($CC --print-file-name=crt1.o)
|
||||
prefix=${prefix-./usr}
|
||||
|
||||
rm -f tcc gcc-tcc
|
||||
touch config.mak
|
||||
make clean
|
||||
rm -f *.a *.o
|
||||
unset ONE_SOURCE
|
||||
unset CFLAGS LDFLAGS
|
||||
|
||||
CPPFLAGS_TCC="
|
||||
-DHAVE_FLOAT=1
|
||||
-DHAVE_BITFIELD=1
|
||||
-DHAVE_LONG_LONG=1
|
||||
-DHAVE_SETJMP=1
|
||||
"
|
||||
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
aarch*)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
CFLAGS=-marm
|
||||
CPP_TARGET_FLAG="-DTCC_CPU_VERSION=7 -DTCC_TARGET_ARM -DTCC_ARM_VFP"
|
||||
;;
|
||||
arm*|aarch*)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-unknown-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
CFLAGS=-marm
|
||||
CPP_TARGET_FLAG="-DTCC_CPU_VERSION=7 -DTCC_TARGET_ARM -DTCC_ARM_VFP"
|
||||
;;
|
||||
*x86_64*)
|
||||
cpu=x86_64
|
||||
mes_cpu=x86_64
|
||||
tcc_cpu=x86_64
|
||||
triplet=x86_64-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
CFLAGS=
|
||||
CPP_TARGET_FLAG="-DTCC_TARGET_X86_64"
|
||||
;;
|
||||
*)
|
||||
cpu=x86
|
||||
mes_cpu=x86
|
||||
tcc_cpu=i386
|
||||
triplet=i686-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
CFLAGS=
|
||||
CPP_TARGET_FLAG="-DTCC_TARGET_I386"
|
||||
;;
|
||||
esac
|
||||
|
||||
./configure --prefix=$prefix --tccdir=$PWD --crtprefix=$crtdir --extra-cflags="$CFLAGS $CPPFLAGS_TCC" --cc=$CC
|
||||
type -p etags && make ETAGS
|
||||
|
||||
#Try building without eabihf
|
||||
#make PROGRAM_PREFIX=gcc- gcc-tcc
|
||||
if [ $mes_cpu = arm ]; then
|
||||
make PROGRAM_PREFIX=gcc- gcc-tcc DEF-arm='$(DEF-arm-vfp)'
|
||||
./gcc-tcc -c $CPP_TARGET_FLAG $CPPFLAGS_TCC $CFLAGS -c lib/libtcc1.c
|
||||
./gcc-tcc -ar cr libtcc1.a libtcc1.o
|
||||
else
|
||||
make PROGRAM_PREFIX=gcc- gcc-tcc
|
||||
rm -f libtcc1.c
|
||||
touch libtcc1.c
|
||||
./gcc-tcc -c libtcc1.c
|
||||
./gcc-tcc -ar cr libtcc1.a libtcc1.o
|
||||
fi
|
||||
make libtcc1.a
|
||||
rm -rf gcc-tcc-usr
|
||||
mkdir -p gcc-tcc-usr
|
||||
cp *.o *.a gcc-tcc-usr
|
||||
rm -rf $prefix
|
||||
mkdir -p $prefix/lib/tcc
|
||||
cp libtcc1.a $prefix/lib/tcc
|
|
@ -0,0 +1,256 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
export V
|
||||
export MESCC
|
||||
export MES_DEBUG
|
||||
export MES_PREFIX
|
||||
export MES_LIB
|
||||
export MES_SOURCE
|
||||
export ONE_SOURCE
|
||||
export PREPROCESS
|
||||
export REBUILD_LIBC
|
||||
|
||||
export cpu
|
||||
export cross_prefix
|
||||
export mes_cpu
|
||||
export prefix
|
||||
export tcc_cpu
|
||||
export triplet
|
||||
|
||||
if test "$V" = 1 -o "$V" = 2; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
unset CPATH C_INCLUDE_PATH LIBRARY_PATH
|
||||
prefix=${prefix-usr}
|
||||
export prefix
|
||||
MESCC=${MESCC-mes-source/pre-inst-env mescc}
|
||||
|
||||
CC=${CC-$MESCC}
|
||||
host=${host-$($CC -dumpmachine 2>/dev/null)}
|
||||
if test -z "$host$host_type"; then
|
||||
mes_cpu=${arch-$(get_machine || uname -m)}
|
||||
else
|
||||
mes_cpu=${host%%-*}
|
||||
fi
|
||||
case "$mes_cpu" in
|
||||
i386|i486|i586|i686|x86)
|
||||
mes_cpu=x86
|
||||
tcc_cpu=i386
|
||||
have_float=${have_float-true}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-true}
|
||||
;;
|
||||
armv4|armv7l|arm)
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
have_float=${have_float-false}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-false}
|
||||
;;
|
||||
amd64)
|
||||
tcc_cpu=x86_64
|
||||
mes_cpu=x86_64
|
||||
have_float=${have_float-true}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-true}
|
||||
;;
|
||||
esac
|
||||
case "$host" in
|
||||
*linux-gnu|*linux)
|
||||
mes_kernel=linux;;
|
||||
*gnu)
|
||||
mes_kernel=gnu;;
|
||||
*)
|
||||
mes_kernel=linux;;
|
||||
esac
|
||||
export mes_cpu
|
||||
export tcc_cpu
|
||||
export have_float
|
||||
export have_long_long
|
||||
export have_setjmp
|
||||
|
||||
MES=${MES-mes-source/bin/mes}
|
||||
MES_PREFIX=${MES_PREFIX-mes}
|
||||
MES_SOURCE=${MES_SOURCE-mes-source}
|
||||
MES_LIB=${MES_LIB-$MES_PREFIX/lib}
|
||||
MES_LIB=$MES_SOURCE/gcc-lib/${mes_cpu}-mes
|
||||
|
||||
PREPROCESS=${PREPROCESS-true}
|
||||
ONE_SOURCE=${ONE_SOURCE-false}
|
||||
|
||||
interpreter=/lib/mes-loader
|
||||
rm -f tcc.E tcc.hex2 tcc.M1 tcc.m1 mes-tcc boot?-tcc
|
||||
|
||||
verbose=
|
||||
if test "$V" = 1; then
|
||||
MESCCFLAGS="$MESCCFLAGS -v"
|
||||
elif test "$V" = 2; then
|
||||
MESCCFLAGS="$MESCCFLAGS -v -v"
|
||||
fi
|
||||
|
||||
mkdir -p $prefix/lib
|
||||
|
||||
if test "$V" = 2; then
|
||||
sh $MESCC --help
|
||||
fi
|
||||
|
||||
if $ONE_SOURCE; then
|
||||
sh cc.sh tcc
|
||||
files="tcc.S"
|
||||
else
|
||||
sh cc.sh tccpp
|
||||
sh cc.sh tccgen
|
||||
sh cc.sh tccelf
|
||||
sh cc.sh tccrun
|
||||
sh cc.sh ${tcc_cpu}-gen
|
||||
sh cc.sh ${tcc_cpu}-link
|
||||
sh cc.sh ${tcc_cpu}-asm
|
||||
sh cc.sh tccasm
|
||||
sh cc.sh libtcc
|
||||
sh cc.sh tcc
|
||||
files="
|
||||
tccpp.S
|
||||
tccgen.S
|
||||
tccelf.S
|
||||
tccrun.S
|
||||
${tcc_cpu}-gen.S
|
||||
${tcc_cpu}-link.S
|
||||
${tcc_cpu}-asm.S
|
||||
tccasm.S
|
||||
libtcc.S
|
||||
tcc.S
|
||||
"
|
||||
fi
|
||||
|
||||
$MESCC \
|
||||
$MESCCFLAGS \
|
||||
-g \
|
||||
-o mes-tcc \
|
||||
-L $MES_SOURCE/mescc-lib \
|
||||
-L $MES_SOURCE/lib \
|
||||
$files \
|
||||
-l c+tcc
|
||||
|
||||
CC="./mes-tcc"
|
||||
AR="./mes-tcc -ar"
|
||||
CPPFLAGS="
|
||||
-I $MES_PREFIX/include
|
||||
-I $MES_PREFIX/include/$mes_kernel/$mes_cpu
|
||||
-I $MES_PREFIX/lib
|
||||
-D BOOTSTRAP=1
|
||||
"
|
||||
|
||||
if test "$mes_cpu" = x86; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_I386=1"
|
||||
elif test "$mes_cpu" = arm; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_ARM=1 -D TCC_ARM_VFP=1 -D CONFIG_TCC_LIBTCC1_MES=1"
|
||||
elif test "$mes_cpu" = x86_64; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_X86_64=1"
|
||||
elif test "$mes_cpu" = riscv64; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_RISCV64=1 -D CONFIG_TCC_LIBTCC1_MES=1"
|
||||
else
|
||||
echo "cpu not supported: $mes_cpu"
|
||||
fi
|
||||
|
||||
CFLAGS=
|
||||
|
||||
REBUILD_LIBC=${REBUILD_LIBC-true}
|
||||
|
||||
mkdir -p $prefix/lib/tcc
|
||||
if $REBUILD_LIBC; then
|
||||
for i in 1 i n; do
|
||||
rm -f crt$i.o;
|
||||
cp -f $MES_LIB//crt$i.c .
|
||||
$CC $CPPFLAGS $CFLAGS -static -nostdlib -nostdinc -c crt$i.c
|
||||
done
|
||||
|
||||
rm -f libc.a
|
||||
cp -f $MES_LIB/libc+gnu.c libc.c
|
||||
$CC -c $CPPFLAGS $CFLAGS libc.c
|
||||
$AR cr libc.a libc.o
|
||||
|
||||
rm -f libtcc1.a
|
||||
cp -f $MES_LIB/libtcc1.c .
|
||||
$CC -c $CPPFLAGS $CPP_TARGET_FLAG $CFLAGS lib/libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o
|
||||
|
||||
if [ $mes_cpu = arm ]; then
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG lib/armeabi.c
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG -o libtcc1-tcc.o lib/libtcc1.c
|
||||
$AR rc libtcc1-tcc.a libtcc1-tcc.o armeabi.o
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS -D HAVE_FLOAT=1 -D HAVE_LONG_LONG=1 -o libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
$AR cr libtcc1-mes.a libtcc1-mes.o armeabi.o
|
||||
|
||||
$CC -c -g $CPP_TARGET_FLAG $CFLAGS -o libtcc1.o lib/libtcc1.c
|
||||
# $AR cr libtcc1.a libtcc1.o armeabi.o
|
||||
$AR cr libtcc1.a libtcc1.o
|
||||
|
||||
cp -f libtcc1-tcc.a $prefix/lib/tcc
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
|
||||
if [ $mes_cpu = riscv64 ]; then
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG lib/lib-arm64.c
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS $CPP_TARGET_FLAG -o libtcc1-tcc.o lib/libtcc1.c
|
||||
$AR rc libtcc1-tcc.a libtcc1-tcc.o lib-arm64.o
|
||||
|
||||
$CC -c -g $CPPFLAGS $CFLAGS -D HAVE_FLOAT=1 -D HAVE_LONG_LONG=1 -o libtcc1-mes.o $MES_LIB/libtcc1.c
|
||||
$AR cr libtcc1-mes.a libtcc1-mes.o lib-arm64.o
|
||||
|
||||
$CC -c -g $CPP_TARGET_FLAG $CFLAGS -o libtcc1.o lib/libtcc1.c
|
||||
$AR cr libtcc1.a libtcc1.o
|
||||
|
||||
cp -f libtcc1-tcc.a $prefix/lib/tcc
|
||||
cp -f libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
|
||||
rm -f libgetopt.a
|
||||
cp -f $MES_LIB/libgetopt.c .
|
||||
$CC -c $CPPFLAGS $CFLAGS libgetopt.c
|
||||
$AR cr libgetopt.a libgetopt.o
|
||||
else
|
||||
cp -f $MES_LIB/crt1.o .
|
||||
cp -f $MES_LIB/crti.o .
|
||||
cp -f $MES_LIB/crtn.o .
|
||||
cp -f $MES_LIB/libc+gnu.a libc.a
|
||||
cp -f $MES_LIB/libtcc1.a .
|
||||
cp -f $MES_LIB/libgetopt.a .
|
||||
|
||||
if [ $mes_cpu = arm ]; then
|
||||
$CC -c $CPPFLAGS $CFLAGS $MES_LIB/libtcc1.c
|
||||
$CC -c $CPPFLAGS $CFLAGS lib/armeabi.c
|
||||
fi
|
||||
if [ $mes_cpu = riscv64]; then
|
||||
$CC -c $CPPFLAGS $CFLAGS $MES_LIB/libtcc1.c
|
||||
$CC -c $CPPFLAGS $CFLAGS lib/lib-arm64.c
|
||||
fi
|
||||
fi
|
||||
|
||||
cp -f libc.a $prefix/lib
|
||||
cp -f libtcc1.a $prefix/lib/tcc
|
||||
cp -f libgetopt.a $prefix/lib
|
||||
|
||||
rm -rf mes-usr
|
||||
mkdir -p mes-usr
|
||||
cp *.M1 mes-usr
|
||||
cp *.S mes-usr
|
||||
cp *.a mes-usr
|
||||
|
||||
REBUILD_LIBC=true
|
||||
TCC=./mes-tcc sh boot.sh
|
||||
TCC=./boot0-tcc sh boot.sh
|
||||
TCC=./boot1-tcc sh boot.sh
|
||||
TCC=./boot2-tcc sh boot.sh
|
||||
TCC=./boot3-tcc sh boot.sh
|
||||
TCC=./boot4-tcc sh boot.sh
|
||||
TCC=./boot5-tcc sh boot.sh
|
||||
cmp boot5-tcc boot6-tcc
|
||||
cp -f boot5-tcc tcc
|
||||
|
||||
echo "build.sh: done"
|
|
@ -0,0 +1,72 @@
|
|||
#! /bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$V" = 1 -o "$V" = 2 ]; then
|
||||
set -x
|
||||
MESCCFLAGS="$MESCCFLAGS -v"
|
||||
fi
|
||||
|
||||
t=$1
|
||||
|
||||
rm -f $t.E $t.M1 $t.m1
|
||||
|
||||
MES=${MES-mes-source/bin/mes}
|
||||
MESCC=${MESCC-mes-source/pre-inst-env mescc}
|
||||
CFLAGS=${CFLAGS-}
|
||||
MES_PREFIX=${MES_PREFIX-mes-source}
|
||||
absprefix=$(cd $prefix && pwd)
|
||||
interpreter=/lib/mes-loader
|
||||
|
||||
ulimit -s 17030
|
||||
|
||||
CPPFLAGS="
|
||||
-I $MES_PREFIX/lib
|
||||
-I $MES_PREFIX/include
|
||||
-D BOOTSTRAP=1
|
||||
"
|
||||
|
||||
if test "$mes_cpu" = x86; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_I386=1"
|
||||
elif test "$mes_cpu" = arm; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_ARM=1 -D TCC_ARM_VFP=1 -D CONFIG_TCC_LIBTCC1_MES=1"
|
||||
elif test "$mes_cpu" = x86_64; then
|
||||
CPP_TARGET_FLAG="-D TCC_TARGET_X86_64=1"
|
||||
else
|
||||
echo "cpu not supported: $mes_cpu"
|
||||
fi
|
||||
|
||||
CPPFLAGS_TCC="$CPPFLAGS
|
||||
-I .
|
||||
$CPP_TARGET_FLAG
|
||||
-D inline=
|
||||
-D CONFIG_TCCDIR=\"$prefix/lib/tcc\"
|
||||
-D CONFIG_TCC_CRTPREFIX=\"$prefix/lib:"{B}"/lib:.\"
|
||||
-D CONFIG_TCC_ELFINTERP=\"$interpreter\"
|
||||
-D CONFIG_TCC_LIBPATHS=\"$prefix/lib:"{B}"/lib:.\"
|
||||
-D CONFIG_TCC_SYSINCLUDEPATHS=\"$MES_PREFIX/include:$prefix/include:"{B}"/include\"
|
||||
-D TCC_LIBGCC=\"$prefix/lib/libc.a\"
|
||||
-D TCC_LIBTCC1_MES=\"libtcc1-mes.a\"
|
||||
-D CONFIG_TCCBOOT=1
|
||||
-D CONFIG_TCC_STATIC=1
|
||||
-D CONFIG_USE_LIBGCC=1
|
||||
-D TCC_MES_LIBC=1
|
||||
"
|
||||
|
||||
if $ONE_SOURCE; then
|
||||
CPPFLAGS_TCC="$CPPFLAGS_TCC -D ONE_SOURCE=$ONE_SOURCE"
|
||||
fi
|
||||
|
||||
if $PREPROCESS; then
|
||||
time sh $MESCC $MESCCFLAGS -E -o $t.E \
|
||||
$CFLAGS \
|
||||
$CPPFLAGS_TCC \
|
||||
$t.c
|
||||
time sh $MESCC $MESCCFLAGS -S -o $t.M1 $t.E
|
||||
else
|
||||
time sh $MESCC $MESCCFLAGS -S -o $t.M1 \
|
||||
$CFLAGS \
|
||||
$CPPFLAGS_TCC \
|
||||
$t.c
|
||||
fi
|
||||
|
||||
tr -d '\r' < $t.M1 > $t.S
|
|
@ -0,0 +1,423 @@
|
|||
#! /usr/bin/env bash
|
||||
|
||||
export V
|
||||
if test "$V" = 1 -o "$V" = 2; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
aarch*)
|
||||
cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
arm*|aarch*)
|
||||
cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-unknown-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
riscv64*)
|
||||
cpu=riscv64
|
||||
tcc_cpu=riscv64
|
||||
triplet=riscv64-unknown-linux
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
*)
|
||||
cpu=x86
|
||||
tcc_cpu=i386
|
||||
triplet=i686-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
esac
|
||||
export cpu
|
||||
export cross_prefix
|
||||
export tcc_cpu
|
||||
export triplet
|
||||
|
||||
GCC_TCC=${GCC_TCC-./${cross_prefix}tcc}
|
||||
TCC=${TCC-./tcc}
|
||||
MES_PREFIX=${MES_PREFIX-mes}
|
||||
MES_SOURCE=${MES_SOURCE-mes-source}
|
||||
export MES_PREFIX
|
||||
export MES_SOURCE
|
||||
|
||||
mkdir -p lib/tests
|
||||
cp -r $MES_SOURCE/lib/tests lib
|
||||
|
||||
mes_tests="
|
||||
lib/tests/scaffold/t.c
|
||||
lib/tests/scaffold/01-return-0.c
|
||||
lib/tests/scaffold/02-return-1.c
|
||||
lib/tests/scaffold/03-call.c
|
||||
lib/tests/scaffold/04-call-0.c
|
||||
lib/tests/scaffold/05-call-1.c
|
||||
lib/tests/scaffold/06-call-not-1.c
|
||||
lib/tests/scaffold/06-not-call-1.c
|
||||
lib/tests/scaffold/06-call-2.c
|
||||
lib/tests/scaffold/06-call-string.c
|
||||
lib/tests/scaffold/06-call-variable.c
|
||||
lib/tests/scaffold/06-return-void.c
|
||||
lib/tests/scaffold/07-include.c
|
||||
lib/tests/scaffold/08-assign.c
|
||||
lib/tests/scaffold/08-assign-negative.c
|
||||
lib/tests/scaffold/08-assign-global.c
|
||||
lib/tests/scaffold/10-if-0.c
|
||||
lib/tests/scaffold/11-if-1.c
|
||||
lib/tests/scaffold/12-if-eq.c
|
||||
lib/tests/scaffold/13-if-neq.c
|
||||
lib/tests/scaffold/14-if-goto.c
|
||||
lib/tests/scaffold/15-if-not-f.c
|
||||
lib/tests/scaffold/16-if-t.c
|
||||
lib/tests/scaffold/17-compare-char.c
|
||||
lib/tests/scaffold/17-compare-ge.c
|
||||
lib/tests/scaffold/17-compare-gt.c
|
||||
lib/tests/scaffold/17-compare-le.c
|
||||
lib/tests/scaffold/17-compare-lt.c
|
||||
lib/tests/scaffold/17-compare-unsigned-ge.c
|
||||
lib/tests/scaffold/17-compare-unsigned-gt.c
|
||||
lib/tests/scaffold/17-compare-unsigned-le.c
|
||||
lib/tests/scaffold/17-compare-unsigned-lt.c
|
||||
lib/tests/scaffold/17-compare-unsigned-char-le.c
|
||||
lib/tests/scaffold/17-compare-unsigned-short-le.c
|
||||
lib/tests/scaffold/17-compare-unsigned-long-le.c
|
||||
lib/tests/scaffold/17-compare-and.c
|
||||
lib/tests/scaffold/17-compare-or.c
|
||||
lib/tests/scaffold/17-compare-and-or.c
|
||||
lib/tests/scaffold/17-compare-assign.c
|
||||
lib/tests/scaffold/17-compare-call.c
|
||||
lib/tests/scaffold/18-assign-shadow.c
|
||||
lib/tests/scaffold/20-while.c
|
||||
lib/tests/scaffold/21-char-array-simple.c
|
||||
lib/tests/scaffold/21-char-array.c
|
||||
lib/tests/scaffold/22-while-char-array.c
|
||||
lib/tests/scaffold/23-global-pointer-init-null.c
|
||||
lib/tests/scaffold/23-global-pointer-init.c
|
||||
lib/tests/scaffold/23-global-pointer-ref.c
|
||||
lib/tests/scaffold/23-global-pointer-pointer-ref.c
|
||||
lib/tests/scaffold/23-pointer-sub.c
|
||||
lib/tests/scaffold/23-pointer.c
|
||||
lib/tests/mes/30-oputs.c
|
||||
lib/tests/mes/30-eputs.c
|
||||
lib/tests/string/30-strlen.c
|
||||
lib/tests/scaffold/30-exit-0.c
|
||||
lib/tests/scaffold/30-exit-42.c
|
||||
lib/tests/scaffold/32-call-wrap.c
|
||||
lib/tests/scaffold/32-compare.c
|
||||
lib/tests/scaffold/33-and-or.c
|
||||
lib/tests/scaffold/34-pre-post.c
|
||||
lib/tests/scaffold/35-compare-char.c
|
||||
lib/tests/scaffold/36-compare-arithmetic.c
|
||||
lib/tests/scaffold/36-compare-arithmetic-negative.c
|
||||
lib/tests/scaffold/37-compare-assign.c
|
||||
lib/tests/scaffold/38-compare-call-2.c
|
||||
lib/tests/scaffold/38-compare-call-3.c
|
||||
lib/tests/scaffold/38-compare-call.c
|
||||
lib/tests/scaffold/40-if-else.c
|
||||
lib/tests/scaffold/41-ternary.c
|
||||
lib/tests/scaffold/42-goto-label.c
|
||||
lib/tests/scaffold/43-for-do-while.c
|
||||
lib/tests/scaffold/44-switch.c
|
||||
lib/tests/scaffold/44-switch-fallthrough.c
|
||||
lib/tests/scaffold/44-switch-body-fallthrough.c
|
||||
lib/tests/scaffold/45-void-call.c
|
||||
lib/tests/scaffold/46-function-static.c
|
||||
lib/tests/scaffold/47-function-expression.c
|
||||
lib/tests/scaffold/48-global-static.c
|
||||
lib/tests/assert/50-assert.c
|
||||
lib/tests/mes/50-itoa.c
|
||||
lib/tests/posix/50-getenv.c
|
||||
lib/tests/stdlib/50-malloc.c
|
||||
lib/tests/string/50-strcmp.c
|
||||
lib/tests/string/50-strcmp-itoa.c
|
||||
lib/tests/string/50-strcpy.c
|
||||
lib/tests/string/50-strncmp.c
|
||||
lib/tests/posix/50-open-read.c
|
||||
lib/tests/scaffold/51-pointer-sub.c
|
||||
lib/tests/scaffold/54-argc.c
|
||||
lib/tests/scaffold/54-argv.c
|
||||
lib/tests/scaffold/55-char-array.c
|
||||
lib/tests/scaffold/60-math.c
|
||||
lib/tests/scaffold/60-math-itoa.c
|
||||
lib/tests/scaffold/61-array.c
|
||||
lib/tests/scaffold/62-array.c
|
||||
lib/tests/scaffold/63-struct.c
|
||||
lib/tests/scaffold/63-struct-pointer.c
|
||||
lib/tests/scaffold/63-struct-local.c
|
||||
lib/tests/scaffold/63-struct-function.c
|
||||
lib/tests/scaffold/63-struct-assign.c
|
||||
lib/tests/scaffold/63-struct-array.c
|
||||
lib/tests/scaffold/63-struct-array-assign.c
|
||||
lib/tests/scaffold/63-struct-array-compare.c
|
||||
lib/tests/scaffold/63-struct-cell.c
|
||||
lib/tests/scaffold/64-make-cell.c
|
||||
lib/tests/scaffold/65-read.c
|
||||
lib/tests/scaffold/66-local-char-array.c
|
||||
"
|
||||
|
||||
tcc_tests="
|
||||
lib/tests/scaffold/70-stdarg.c
|
||||
lib/tests/stdio/70-printf-hello.c
|
||||
lib/tests/stdio/70-printf-simple.c
|
||||
lib/tests/stdio/70-printf.c
|
||||
lib/tests/stdlib/70-strtoull.c
|
||||
lib/tests/string/70-strchr.c
|
||||
lib/tests/scaffold/71-struct-array.c
|
||||
lib/tests/scaffold/72-typedef-struct-def.c
|
||||
lib/tests/scaffold/72-typedef-struct-def-local.c
|
||||
lib/tests/scaffold/73-union-hello.c
|
||||
lib/tests/scaffold/73-union.c
|
||||
lib/tests/scaffold/74-multi-line-string.c
|
||||
lib/tests/scaffold/75-struct-union.c
|
||||
lib/tests/scaffold/76-pointer-arithmetic-pp.c
|
||||
lib/tests/scaffold/76-pointer-arithmetic.c
|
||||
lib/tests/scaffold/77-pointer-assign.c
|
||||
lib/tests/scaffold/78-union-struct.c
|
||||
lib/tests/scaffold/79-int-array-simple.c
|
||||
lib/tests/scaffold/79-int-array.c
|
||||
lib/tests/scaffold/7a-struct-char-array.c
|
||||
lib/tests/scaffold/7b-struct-int-array-hello.c
|
||||
lib/tests/scaffold/7b-struct-int-array-pointer.c
|
||||
lib/tests/scaffold/7b-struct-int-array.c
|
||||
lib/tests/scaffold/7c-dynarray.c
|
||||
lib/tests/scaffold/7d-cast-char.c
|
||||
lib/tests/scaffold/7e-struct-array-access.c
|
||||
lib/tests/scaffold/7f-struct-pointer-arithmetic.c
|
||||
lib/tests/scaffold/7g-struct-byte-word-field.c
|
||||
lib/tests/scaffold/7h-struct-assign.c
|
||||
lib/tests/scaffold/7i-struct-struct-simple.c
|
||||
lib/tests/scaffold/7i-struct-struct.c
|
||||
lib/tests/scaffold/7k-empty-for.c
|
||||
lib/tests/scaffold/7k-for-each-elem-simple.c
|
||||
lib/tests/scaffold/7k-for-each-elem.c
|
||||
lib/tests/scaffold/7l-struct-any-size-array-simple.c
|
||||
lib/tests/scaffold/7l-struct-any-size-array.c
|
||||
lib/tests/scaffold/7m-struct-char-array-assign.c
|
||||
lib/tests/scaffold/7n-struct-struct-array.c
|
||||
lib/tests/scaffold/7o-struct-pre-post-simple.c
|
||||
lib/tests/scaffold/7o-struct-pre-post.c
|
||||
lib/tests/scaffold/7p-struct-cast.c
|
||||
lib/tests/scaffold/7q-bit-field-simple.c
|
||||
lib/tests/scaffold/7q-bit-field.c
|
||||
lib/tests/scaffold/7r-sign-extend.c
|
||||
lib/tests/scaffold/7s-struct-short.c
|
||||
lib/tests/scaffold/7s-unsigned-compare.c
|
||||
lib/tests/scaffold/7t-function-destruct.c
|
||||
lib/tests/scaffold/7u-double.c
|
||||
lib/tests/scaffold/7u-long-long.c
|
||||
lib/tests/scaffold/7u-ternary-expression.c
|
||||
lib/tests/scaffold/7u-call-ternary.c
|
||||
lib/tests/scaffold/7u-inc-byte-word.c
|
||||
lib/tests/scaffold/7u-struct-func.c
|
||||
lib/tests/scaffold/7u-struct-size10.c
|
||||
lib/tests/scaffold/7u-vstack.c
|
||||
lib/tests/scaffold/70-array-in-struct-init.c
|
||||
lib/tests/scaffold/70-struct-short-enum-init.c
|
||||
lib/tests/scaffold/70-struct-post.c
|
||||
lib/tests/scaffold/70-extern.c
|
||||
lib/tests/scaffold/70-ternary-arithmetic-argument.c
|
||||
lib/tests/setjmp/80-setjmp.c
|
||||
lib/tests/stdio/80-sscanf.c
|
||||
lib/tests/stdlib/80-qsort.c
|
||||
lib/tests/stdlib/80-qsort-dupes.c
|
||||
lib/tests/string/80-strncpy.c
|
||||
lib/tests/string/80-strrchr.c
|
||||
lib/tests/scaffold/82-define.c
|
||||
lib/tests/scaffold/83-heterogenoous-init.c
|
||||
lib/tests/scaffold/84-struct-field-list.c
|
||||
lib/tests/scaffold/85-sizeof.c
|
||||
"
|
||||
|
||||
gnu_tests="
|
||||
lib/tests/dirent/90-readdir.c
|
||||
lib/tests/io/90-stat.c
|
||||
lib/tests/mes/90-abtod.c
|
||||
lib/tests/mes/90-dtoab.c
|
||||
lib/tests/posix/90-execlp.c
|
||||
lib/tests/posix/90-unsetenv.c
|
||||
lib/tests/signal/90-signal.c
|
||||
lib/tests/stdio/90-fopen.c
|
||||
lib/tests/stdio/90-fopen-append.c
|
||||
lib/tests/stdio/90-fread-fwrite.c
|
||||
lib/tests/stdio/90-fseek.c
|
||||
lib/tests/stdio/90-sprintf.c
|
||||
lib/tests/stdlib/90-strtol.c
|
||||
lib/tests/string/90-snprintf.c
|
||||
lib/tests/string/90-strpbrk.c
|
||||
lib/tests/string/90-strspn.c
|
||||
lib/tests/scaffold/90-goto-var.c
|
||||
lib/tests/scaffold/91-goto-array.c
|
||||
lib/tests/scaffold/a0-call-trunc-char.c
|
||||
lib/tests/scaffold/a0-call-trunc-short.c
|
||||
lib/tests/scaffold/a0-call-trunc-int.c
|
||||
lib/tests/scaffold/a0-math-divide-signed-negative.c
|
||||
lib/tests/scaffold/a1-global-no-align.c
|
||||
lib/tests/scaffold/a1-global-no-clobber.c
|
||||
"
|
||||
|
||||
tests="$mes_tests$tcc_tests$gnu_tests"
|
||||
|
||||
broken="
|
||||
lib/tests/scaffold/t.c
|
||||
lib/tests/scaffold/70-ternary-arithmetic-argument.c
|
||||
lib/tests/dirent/90-readdir.c
|
||||
lib/tests/io/90-stat.c
|
||||
lib/tests/stdio/90-fseek.c
|
||||
"
|
||||
|
||||
if [ $TCC = ./tcc ]; then
|
||||
broken="$broken
|
||||
lib/tests/scaffold/60-math.c
|
||||
lib/tests/scaffold/7s-unsigned-compare.c
|
||||
"
|
||||
fi
|
||||
|
||||
if [ $tcc_cpu = "arm" ]; then
|
||||
broken="$broken
|
||||
lib/tests/setjmp/80-setjmp.c
|
||||
lib/tests/mes/90-abtod.c
|
||||
lib/tests/signal/90-signal.c
|
||||
"
|
||||
fi
|
||||
|
||||
if [ ! -x $GCC_TCC ]; then
|
||||
broken="$broken
|
||||
02-return-1
|
||||
05-call-1
|
||||
"
|
||||
fi
|
||||
|
||||
if ! test -f lib/tests/scaffold/t.c; then
|
||||
tests=
|
||||
broken=
|
||||
fi
|
||||
|
||||
expect=$(echo $broken | wc -w)
|
||||
mkdir -p scaffold/tests
|
||||
|
||||
set +e
|
||||
pass=0
|
||||
fail=0
|
||||
total=0
|
||||
for t in $tests; do
|
||||
b=$(basename "$t" .c)
|
||||
sh test.sh "$t" &> "$t".log
|
||||
r=$?
|
||||
total=$((total+1))
|
||||
if [ $r = 0 ]; then
|
||||
echo $t: [OK]
|
||||
pass=$((pass+1))
|
||||
else
|
||||
echo $t: [FAIL]
|
||||
fail=$((fail+1))
|
||||
fi
|
||||
done
|
||||
|
||||
tests="
|
||||
tests/tests2/00_assignment.c
|
||||
tests/tests2/01_comment.c
|
||||
tests/tests2/02_printf.c
|
||||
tests/tests2/03_struct.c
|
||||
tests/tests2/04_for.c
|
||||
tests/tests2/05_array.c
|
||||
tests/tests2/06_case.c
|
||||
tests/tests2/07_function.c
|
||||
tests/tests2/08_while.c
|
||||
tests/tests2/09_do_while.c
|
||||
|
||||
tests/tests2/10_pointer.c
|
||||
tests/tests2/11_precedence.c
|
||||
tests/tests2/12_hashdefine.c
|
||||
tests/tests2/13_integer_literals.c
|
||||
tests/tests2/14_if.c
|
||||
tests/tests2/15_recursion.c
|
||||
tests/tests2/16_nesting.c
|
||||
tests/tests2/17_enum.c
|
||||
tests/tests2/18_include.c
|
||||
tests/tests2/19_pointer_arithmetic.c
|
||||
|
||||
tests/tests2/20_pointer_comparison.c
|
||||
tests/tests2/21_char_array.c
|
||||
tests/tests2/22_floating_point.c
|
||||
tests/tests2/23_type_coercion.c
|
||||
tests/tests2/24_math_library.c
|
||||
tests/tests2/25_quicksort.c
|
||||
tests/tests2/26_character_constants.c
|
||||
tests/tests2/27_sizeof.c
|
||||
tests/tests2/28_strings.c
|
||||
tests/tests2/29_array_address.c
|
||||
|
||||
tests/tests2/30_hanoi.c
|
||||
tests/tests2/31_args.c
|
||||
tests/tests2/32_led.c
|
||||
tests/tests2/33_ternary_op.c
|
||||
tests/tests2/34_array_assignment.c
|
||||
tests/tests2/35_sizeof.c
|
||||
tests/tests2/36_array_initialisers.c
|
||||
tests/tests2/37_sprintf.c
|
||||
tests/tests2/38_multiple_array_index.c
|
||||
tests/tests2/39_typedef.c
|
||||
|
||||
tests/tests2/40_stdio.c
|
||||
tests/tests2/41_hashif.c
|
||||
tests/tests2/42_function_pointer.c
|
||||
tests/tests2/43_void_param.c
|
||||
tests/tests2/44_scoped_declarations.c
|
||||
tests/tests2/45_empty_for.c
|
||||
tests/tests2/47_switch_return.c
|
||||
tests/tests2/48_nested_break.c
|
||||
tests/tests2/49_bracket_evaluation.c
|
||||
|
||||
tests/tests2/50_logical_second_arg.c
|
||||
tests/tests2/51_static.c
|
||||
tests/tests2/52_unnamed_enum.c
|
||||
tests/tests2/54_goto.c
|
||||
tests/tests2/55_lshift_type.c
|
||||
"
|
||||
|
||||
broken="$broken
|
||||
tests/tests2/22_floating_point.c
|
||||
tests/tests2/23_type_coercion.c
|
||||
tests/tests2/24_math_library.c
|
||||
tests/tests2/34_array_assignment.c
|
||||
tests/tests2/49_bracket_evaluation.c
|
||||
tests/tests2/55_lshift_type.c
|
||||
"
|
||||
|
||||
#tests/tests2/24_math_library.c ; float, math
|
||||
#tests/tests2/34_array_assignment.c ; fails with GCC
|
||||
|
||||
expect=$(echo $broken | wc -w)
|
||||
for t in $tests; do
|
||||
if [ ! -f "$t" ]; then
|
||||
echo ' [SKIP]'
|
||||
continue;
|
||||
fi
|
||||
b=$(basename "$t" .c)
|
||||
d=$(dirname "$t")
|
||||
sh test.sh "$t" &> "$d/$b".log
|
||||
r=$?
|
||||
total=$((total+1))
|
||||
if [ $r = 0 ]; then
|
||||
echo $t: [OK]
|
||||
pass=$((pass+1))
|
||||
else
|
||||
echo $t: [FAIL]
|
||||
fail=$((fail+1))
|
||||
fi
|
||||
done
|
||||
[ $expect != 0 ] && echo "expect: $expect"
|
||||
[ $fail != 0 ] && echo "failed: $fail"
|
||||
echo "passed: $pass"
|
||||
[ $fail -lt $expect ] && echo "solved: $(($expect - $fail))"
|
||||
echo "total: $total"
|
||||
if [ $fail != 0 -a $fail -gt $expect ]; then
|
||||
echo FAILED: $fail/$total
|
||||
exit 1
|
||||
elif [ $fail != 0 ]; then
|
||||
echo PASS: $pass/$total
|
||||
else
|
||||
echo PASS: $total
|
||||
fi
|
|
@ -0,0 +1,40 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
|
||||
MES_PREFIX=${MES_PREFIX-mes}
|
||||
MES_SOURCE=${MES_SOURCE-mes-source}
|
||||
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
aarch*)
|
||||
cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
arm*|aarch*)
|
||||
cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-unknown-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
*)
|
||||
cpu=x86
|
||||
tcc_cpu=i386
|
||||
triplet=i686-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
esac
|
||||
|
||||
rm -f *.$triplet-o *.mes-o
|
||||
rm -f 1 2 1.elf 2.elf 1.a 2.a
|
||||
|
||||
# trivial object
|
||||
./tcc -c -I $MES_PREFIX/include $MES_SOURCE/scaffold/main.c 2>/dev/null
|
||||
./$triplet-tcc -o main.$triplet-o -c -I $MES_PREFIX/include $MES_SOURCE/scaffold/main.c 2> 1
|
||||
set +e
|
||||
./mes-tcc -o main.mes-o -c -I $MES_PREFIX/include $MES_SOURCE/scaffold/main.c &> 2
|
||||
diff -y 1 2
|
||||
readelf -a main.$triplet-o > 1.elf
|
||||
readelf -a main.mes-o > 2.elf
|
||||
diff -y 1.elf 2.elf || :
|
|
@ -27,7 +27,7 @@ mandir=""
|
|||
infodir=""
|
||||
sysroot=""
|
||||
cross_prefix=""
|
||||
cc="gcc"
|
||||
cc="gcc -g"
|
||||
ar="ar"
|
||||
strip="strip"
|
||||
bigendian="no"
|
||||
|
@ -198,6 +198,9 @@ case "$cpu" in
|
|||
s390)
|
||||
cpu="s390"
|
||||
;;
|
||||
riscv64)
|
||||
cpu="riscv64"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported CPU"
|
||||
exit 1
|
||||
|
@ -340,7 +343,7 @@ if test -z "$cross_prefix" ; then
|
|||
fi
|
||||
|
||||
if test -z "$triplet"; then
|
||||
if test $cpu = "x86_64" -o $cpu = "arm64" ; then
|
||||
if test $cpu = "x86_64" -o $cpu = "arm64" -o $cpu = "riscv64" ; then
|
||||
if test -f "/usr/lib64/crti.o" ; then
|
||||
tcc_lddir="lib64"
|
||||
fi
|
||||
|
|
|
@ -9,6 +9,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
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
rm -f *.o *.a *.E *.hex2 *.mesc-o *.i686-unknown-linux-gnu-o *.M1
|
||||
rm -f 1 2 1.elf 2.elf
|
||||
|
||||
# trivial object
|
||||
set +e
|
||||
./tcc -c -I ../mes/mlibc/include ../mes/scaffold/main.c 2>/dev/null
|
||||
./i686-unknown-linux-gnu-tcc -o main.i686-unknown-linux-gnu-o -c -I ../mes/mlibc/include ../mes/scaffold/main.c 2> 1
|
||||
./tcc.mes -o main.mesc-o -c -I ../mes/mlibc/include ../mes/scaffold/main.c &> 2
|
||||
diff -y 1 2
|
||||
|
||||
readelf -a main.i686-unknown-linux-gnu-o > 1.elf
|
||||
readelf -a main.mesc-o > 2.elf
|
||||
diff -y 1.elf 2.elf
|
||||
|
||||
# trivial bin
|
||||
./tcc ../mes/scaffold/main.c
|
||||
./i686-unknown-linux-gnu-tcc -o a.i686-unknown-linux-gnu-out -I ../mes/mlibc/include ../mes/scaffold/main.c 2> 1.a
|
||||
./tcc.mes -o a.mes-out -I ../mes/mlibc/include ../mes/scaffold/main.c 2> 2.a
|
||||
diff -y 1.a 2.a
|
|
@ -0,0 +1,94 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
|
||||
export V
|
||||
export MES
|
||||
export MESCC
|
||||
export MES_DEBUG
|
||||
export MES_PREFIX
|
||||
export MES_LIB
|
||||
export MES_SOURCE
|
||||
export ONE_SOURCE
|
||||
export PREPROCESS
|
||||
export REBUILD_LIBC
|
||||
|
||||
export cpu
|
||||
export cross_prefix
|
||||
export mes_cpu
|
||||
export prefix
|
||||
export tcc_cpu
|
||||
export triplet
|
||||
|
||||
prefix=usr
|
||||
MES=${MES-mes-source/bin/mes}
|
||||
MES_ARENA=70000000
|
||||
MES_MAX_ARENA=70000000
|
||||
export MES_ARENA MES_MAX_ARENA
|
||||
|
||||
MES=guile
|
||||
MES=${MES-mes-source/bin/mes}
|
||||
MESCC=${MESCC-mes-source/pre-inst-env mescc}
|
||||
|
||||
MES_PREFIX=${MES_PREFIX-mes-source}
|
||||
|
||||
REBUILD_LIBC=${REBUILD_LIBC-true}
|
||||
|
||||
rm -f mes
|
||||
ln -sf $MES_PREFIX mes
|
||||
|
||||
sh build-gcc.sh
|
||||
|
||||
PREPROCESS=${PREPROCESS-true}
|
||||
ONE_SOURCE=${ONE_SOURCE-false}
|
||||
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
aarch*)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
have_float=${have_float-true}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-false}
|
||||
;;
|
||||
arm*|aarch*)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-unknown-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
have_float=${have_float-true}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-false}
|
||||
;;
|
||||
*)
|
||||
cpu=x86
|
||||
mes_cpu=x86
|
||||
tcc_cpu=i386
|
||||
triplet=i686-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
have_float=${have_float-true}
|
||||
have_long_long=${have_long_long-true}
|
||||
have_setjmp=${have_setjmp-true}
|
||||
;;
|
||||
esac
|
||||
export cpu
|
||||
export cross_prefix
|
||||
export tcc_cpu
|
||||
export triplet
|
||||
export have_float
|
||||
export have_long_long
|
||||
export have_setjmp
|
||||
|
||||
MES_LIB=${MES_LIB-$MES_PREFIX/lib}
|
||||
MES_LIB=$MES_SOURCE/gcc-lib/${mes_cpu}-mes
|
||||
|
||||
sh build-32.sh
|
||||
sh build.sh
|
||||
sh compile.sh
|
||||
sh link.sh ||:
|
||||
sh check.sh
|
||||
rm -rf usr
|
||||
sh install.sh
|
141
elf.h
141
elf.h
|
@ -1,3 +1,4 @@
|
|||
|
||||
/* This file defines standard ELF types, structures, and macros.
|
||||
Copyright (C) 1995-2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
@ -27,13 +28,17 @@
|
|||
typedef signed char int8_t;
|
||||
typedef short int int16_t;
|
||||
typedef int int32_t;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef long long int int64_t;
|
||||
#endif
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef unsigned long long int uint64_t;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Standard ELF types. */
|
||||
|
||||
|
@ -47,19 +52,25 @@ typedef int32_t Elf32_Sword;
|
|||
typedef uint32_t Elf64_Word;
|
||||
typedef int32_t Elf64_Sword;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* Types for signed and unsigned 64-bit quantities. */
|
||||
typedef uint64_t Elf32_Xword;
|
||||
typedef int64_t Elf32_Sxword;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef int64_t Elf64_Sxword;
|
||||
#endif
|
||||
|
||||
/* Type of addresses. */
|
||||
typedef uint32_t Elf32_Addr;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef uint64_t Elf64_Addr;
|
||||
#endif
|
||||
|
||||
/* Type of file offsets. */
|
||||
typedef uint32_t Elf32_Off;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef uint64_t Elf64_Off;
|
||||
#endif
|
||||
|
||||
/* Type for section indices, which are 16-bit quantities. */
|
||||
typedef uint16_t Elf32_Section;
|
||||
|
@ -67,7 +78,9 @@ typedef uint16_t Elf64_Section;
|
|||
|
||||
/* Type for version symbol information. */
|
||||
typedef Elf32_Half Elf32_Versym;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef Elf64_Half Elf64_Versym;
|
||||
#endif
|
||||
|
||||
|
||||
/* The ELF file header. This appears at the start of every ELF file. */
|
||||
|
@ -92,6 +105,7 @@ typedef struct
|
|||
Elf32_Half e_shstrndx; /* Section header string table index */
|
||||
} Elf32_Ehdr;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
|
||||
|
@ -109,6 +123,7 @@ typedef struct
|
|||
Elf64_Half e_shnum; /* Section header table entry count */
|
||||
Elf64_Half e_shstrndx; /* Section header string table index */
|
||||
} Elf64_Ehdr;
|
||||
#endif
|
||||
|
||||
/* Fields in the e_ident array. The EI_* macros are indices into the
|
||||
array. The macros under each EI_* macro are the values the byte
|
||||
|
@ -232,7 +247,7 @@ typedef struct
|
|||
|
||||
#define EM_FX66 66 /* Siemens FX66 microcontroller */
|
||||
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
|
||||
#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
|
||||
#define EM_ST7 68 /* STMicroelectronics ST7 8 bit mc */
|
||||
#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
|
||||
#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
|
||||
#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
|
||||
|
@ -262,7 +277,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
|
||||
|
@ -293,6 +309,7 @@ typedef struct
|
|||
Elf32_Word sh_entsize; /* Entry size if section holds table */
|
||||
} Elf32_Shdr;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word sh_name; /* Section name (string tbl index) */
|
||||
|
@ -306,6 +323,7 @@ typedef struct
|
|||
Elf64_Xword sh_addralign; /* Section alignment */
|
||||
Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||
} Elf64_Shdr;
|
||||
#endif
|
||||
|
||||
/* Special section indices. */
|
||||
|
||||
|
@ -381,7 +399,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. */
|
||||
|
@ -399,6 +417,7 @@ typedef struct
|
|||
Elf32_Section st_shndx; /* Section index */
|
||||
} Elf32_Sym;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word st_name; /* Symbol name (string tbl index) */
|
||||
|
@ -408,6 +427,7 @@ typedef struct
|
|||
Elf64_Addr st_value; /* Symbol value */
|
||||
Elf64_Xword st_size; /* Symbol size */
|
||||
} Elf64_Sym;
|
||||
#endif
|
||||
|
||||
/* The syminfo section if available contains additional information about
|
||||
every dynamic symbol. */
|
||||
|
@ -418,11 +438,13 @@ typedef struct
|
|||
Elf32_Half si_flags; /* Per symbol flags */
|
||||
} Elf32_Syminfo;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half si_boundto; /* Direct bindings, symbol bound to */
|
||||
Elf64_Half si_flags; /* Per symbol flags */
|
||||
} Elf64_Syminfo;
|
||||
#endif
|
||||
|
||||
/* Possible values for si_boundto. */
|
||||
#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */
|
||||
|
@ -510,6 +532,7 @@ typedef struct
|
|||
Elf32_Word r_info; /* Relocation type and symbol index */
|
||||
} Elf32_Rel;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* I have seen two different definitions of the Elf64_Rel and
|
||||
Elf64_Rela structures, so we'll leave them out until Novell (or
|
||||
whoever) gets their act together. */
|
||||
|
@ -520,6 +543,7 @@ typedef struct
|
|||
Elf64_Addr r_offset; /* Address */
|
||||
Elf64_Xword r_info; /* Relocation type and symbol index */
|
||||
} Elf64_Rel;
|
||||
#endif
|
||||
|
||||
/* Relocation table entry with addend (in section of type SHT_RELA). */
|
||||
|
||||
|
@ -530,12 +554,14 @@ typedef struct
|
|||
Elf32_Sword r_addend; /* Addend */
|
||||
} Elf32_Rela;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr r_offset; /* Address */
|
||||
Elf64_Xword r_info; /* Relocation type and symbol index */
|
||||
Elf64_Sxword r_addend; /* Addend */
|
||||
} Elf64_Rela;
|
||||
#endif
|
||||
|
||||
/* How to extract and insert information held in the r_info field. */
|
||||
|
||||
|
@ -561,6 +587,7 @@ typedef struct
|
|||
Elf32_Word p_align; /* Segment alignment */
|
||||
} Elf32_Phdr;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word p_type; /* Segment type */
|
||||
|
@ -572,6 +599,7 @@ typedef struct
|
|||
Elf64_Xword p_memsz; /* Segment size in memory */
|
||||
Elf64_Xword p_align; /* Segment alignment */
|
||||
} Elf64_Phdr;
|
||||
#endif
|
||||
|
||||
/* Special value for e_phnum. This indicates that the real number of
|
||||
program headers is too large to fit into e_phnum. Instead the real
|
||||
|
@ -665,6 +693,7 @@ typedef struct
|
|||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Sxword d_tag; /* Dynamic entry type */
|
||||
|
@ -674,6 +703,7 @@ typedef struct
|
|||
Elf64_Addr d_ptr; /* Address value */
|
||||
} d_un;
|
||||
} Elf64_Dyn;
|
||||
#endif
|
||||
|
||||
/* Legal values for d_tag (dynamic entry type). */
|
||||
|
||||
|
@ -817,7 +847,7 @@ typedef struct
|
|||
#define DF_1_EDITED 0x00200000 /* Object is modified after built. */
|
||||
#define DF_1_NORELOC 0x00400000
|
||||
#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */
|
||||
#define DF_1_GLOBAUDIT 0x01000000 /* Global auditin required. */
|
||||
#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */
|
||||
#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */
|
||||
|
||||
/* Flags for the feature selection in DT_FEATURE_1. */
|
||||
|
@ -843,6 +873,7 @@ typedef struct
|
|||
entry */
|
||||
} Elf32_Verdef;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half vd_version; /* Version revision */
|
||||
|
@ -854,7 +885,7 @@ typedef struct
|
|||
Elf64_Word vd_next; /* Offset in bytes to next verdef
|
||||
entry */
|
||||
} Elf64_Verdef;
|
||||
|
||||
#endif
|
||||
|
||||
/* Legal values for vd_version (version revision). */
|
||||
#define VER_DEF_NONE 0 /* No version */
|
||||
|
@ -880,13 +911,14 @@ typedef struct
|
|||
entry */
|
||||
} Elf32_Verdaux;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word vda_name; /* Version or dependency names */
|
||||
Elf64_Word vda_next; /* Offset in bytes to next verdaux
|
||||
entry */
|
||||
} Elf64_Verdaux;
|
||||
|
||||
#endif
|
||||
|
||||
/* Version dependency section. */
|
||||
|
||||
|
@ -901,6 +933,7 @@ typedef struct
|
|||
entry */
|
||||
} Elf32_Verneed;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Half vn_version; /* Version of structure */
|
||||
|
@ -911,7 +944,7 @@ typedef struct
|
|||
Elf64_Word vn_next; /* Offset in bytes to next verneed
|
||||
entry */
|
||||
} Elf64_Verneed;
|
||||
|
||||
#endif
|
||||
|
||||
/* Legal values for vn_version (version revision). */
|
||||
#define VER_NEED_NONE 0 /* No version */
|
||||
|
@ -930,6 +963,7 @@ typedef struct
|
|||
entry */
|
||||
} Elf32_Vernaux;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word vna_hash; /* Hash value of dependency name */
|
||||
|
@ -939,7 +973,7 @@ typedef struct
|
|||
Elf64_Word vna_next; /* Offset in bytes to next vernaux
|
||||
entry */
|
||||
} Elf64_Vernaux;
|
||||
|
||||
#endif
|
||||
|
||||
/* Legal values for vna_flags. */
|
||||
#define VER_FLG_WEAK 0x2 /* Weak version identifier */
|
||||
|
@ -966,6 +1000,7 @@ typedef struct
|
|||
} a_un;
|
||||
} Elf32_auxv_t;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
uint64_t a_type; /* Entry type */
|
||||
|
@ -977,6 +1012,7 @@ typedef struct
|
|||
on 64-bit platforms and vice versa. */
|
||||
} a_un;
|
||||
} Elf64_auxv_t;
|
||||
#endif
|
||||
|
||||
/* Legal values for a_type (entry type). */
|
||||
|
||||
|
@ -1045,12 +1081,14 @@ typedef struct
|
|||
Elf32_Word n_type; /* Type of the note. */
|
||||
} Elf32_Nhdr;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word n_namesz; /* Length of the note's name. */
|
||||
Elf64_Word n_descsz; /* Length of the note's descriptor. */
|
||||
Elf64_Word n_type; /* Type of the note. */
|
||||
} Elf64_Nhdr;
|
||||
#endif
|
||||
|
||||
/* Known names of notes. */
|
||||
|
||||
|
@ -1104,13 +1142,18 @@ typedef struct
|
|||
/* Move records. */
|
||||
typedef struct
|
||||
{
|
||||
#if HAVE_LONG_LONG
|
||||
Elf32_Xword m_value; /* Symbol value. */
|
||||
#else
|
||||
Elf32_Word m_info; /* Size and index. */
|
||||
Elf32_Word m_info_padding;
|
||||
#endif
|
||||
Elf32_Word m_poffset; /* Symbol offset. */
|
||||
Elf32_Half m_repeat; /* Repeat count. */
|
||||
Elf32_Half m_stride; /* Stride info. */
|
||||
} Elf32_Move;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Xword m_value; /* Symbol value. */
|
||||
|
@ -1119,6 +1162,7 @@ typedef struct
|
|||
Elf64_Half m_repeat; /* Repeat count. */
|
||||
Elf64_Half m_stride; /* Stride info. */
|
||||
} Elf64_Move;
|
||||
#endif
|
||||
|
||||
/* Macro to construct move records. */
|
||||
#define ELF32_M_SYM(info) ((info) >> 8)
|
||||
|
@ -1313,7 +1357,7 @@ typedef struct
|
|||
#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */
|
||||
#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */
|
||||
#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */
|
||||
#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */
|
||||
#define R_SPARC_PC_LM22 39 /* Low middle 22 bits of ... */
|
||||
#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */
|
||||
#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */
|
||||
#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */
|
||||
|
@ -1732,6 +1776,7 @@ typedef struct
|
|||
Elf32_Word l_flags; /* Flags */
|
||||
} Elf32_Lib;
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word l_name; /* Name (string table index) */
|
||||
|
@ -1740,7 +1785,7 @@ typedef struct
|
|||
Elf64_Word l_version; /* Interface version */
|
||||
Elf64_Word l_flags; /* Flags */
|
||||
} Elf64_Lib;
|
||||
|
||||
#endif
|
||||
|
||||
/* Legal values for l_flags. */
|
||||
|
||||
|
@ -2494,22 +2539,30 @@ typedef Elf32_Addr Elf32_Conflict;
|
|||
#define R_ARM_CALL 28
|
||||
#define R_ARM_JUMP24 29
|
||||
#define R_ARM_THM_JUMP24 30
|
||||
#define R_ARM_BASE_ABS 31 /* Adjust by program base. */
|
||||
#define R_ARM_ALU_PCREL_7_0 32
|
||||
#define R_ARM_ALU_PCREL_15_8 33
|
||||
#define R_ARM_ALU_PCREL_23_15 34
|
||||
#define R_ARM_LDR_SBREL_11_0 35
|
||||
#define R_ARM_ALU_SBREL_19_12 36
|
||||
#define R_ARM_ALU_SBREL_27_20 37
|
||||
#define R_ARM_TARGET1 38
|
||||
#define R_ARM_SBREL31 39 /* Program base relative. */
|
||||
#define R_ARM_V4BX 40
|
||||
#define R_ARM_TARGET2 41
|
||||
#define R_ARM_PREL31 42
|
||||
#define R_ARM_MOVW_ABS_NC 43
|
||||
#define R_ARM_MOVT_ABS 44
|
||||
#define R_ARM_MOVW_PREL_NC 45 /* PC relative 16-bit (MOVW). */
|
||||
#define R_ARM_MOVT_PREL 46 /* PC relative (MOVT). */
|
||||
#define R_ARM_THM_MOVW_ABS_NC 47
|
||||
#define R_ARM_THM_MOVT_ABS 48
|
||||
/* Values from 49 to 89 are not yet used/handled by tcc. */
|
||||
#define R_ARM_TLS_GOTDESC 90
|
||||
#define R_ARM_TLS_CALL 91
|
||||
#define R_ARM_TLS_DESCSEQ 92
|
||||
#define R_ARM_THM_TLS_CALL 93
|
||||
#define R_ARM_GOT_PREL 96
|
||||
#define R_ARM_GNU_VTENTRY 100
|
||||
#define R_ARM_GNU_VTINHERIT 101
|
||||
#define R_ARM_THM_PC11 102 /* thumb unconditional branch */
|
||||
|
@ -2907,6 +2960,8 @@ typedef Elf32_Addr Elf32_Conflict;
|
|||
|
||||
#define R_X86_64_NUM 43
|
||||
|
||||
/* x86-64 sh_type values. */
|
||||
#define SHT_X86_64_UNWIND 0x70000001 /* Unwind information. */
|
||||
|
||||
/* AM33 relocations. */
|
||||
#define R_MN10300_NONE 0 /* No reloc. */
|
||||
|
@ -3233,5 +3288,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 */
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
(list (channel
|
||||
(name 'guix)
|
||||
(url "https://git.savannah.gnu.org/git/guix.git")
|
||||
(branch "master")
|
||||
(commit
|
||||
"a0d2ecde943bd1854ddbb7c0cad35a1fc64dc5ab")))
|
|
@ -0,0 +1,624 @@
|
|||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2012-2023 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2014 Andreas Enge <andreas@enge.fr>
|
||||
;;; Copyright © 2012 Nikita Karetnikov <nikita@karetnikov.org>
|
||||
;;; Copyright © 2014, 2015, 2017 Mark H Weaver <mhw@netris.org>
|
||||
;;; Copyright © 2017, 2018, 2019, 2021, 2022 Efraim Flashner <efraim@flashner.co.il>
|
||||
;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
|
||||
;;; Copyright © 2018, 2019, 2020, 2021, 2022, 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
|
||||
;;; Copyright © 2019-2022 Marius Bakke <marius@gnu.org>
|
||||
;;; Copyright © 2020, 2022 Timothy Sample <samplet@ngyro.com>
|
||||
;;; Copyright © 2020 Guy Fleury Iteriteka <gfleury@disroot.org>
|
||||
;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
|
||||
;;; Copyright © 2021 Chris Marusich <cmmarusich@gmail.com>
|
||||
;;; Copyright © 2021 Julien Lepiller <julien@lepiller.eu>
|
||||
;;; Copyright © 2022 Ricardo Wurmus <rekado@elephly.net>
|
||||
;;; Copyright © 2022 Ekaitz Zarraga <ekaitz@elenq.tech>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
;;;
|
||||
;;; GNU Guix is free software; you can redistribute it and/or modify it
|
||||
;;; under the terms of the GNU General Public License as published by
|
||||
;;; the Free Software Foundation; either version 3 of the License, or (at
|
||||
;;; your option) any later version.
|
||||
;;;
|
||||
;;; GNU Guix is distributed in the hope that it will be useful, but
|
||||
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;;; GNU General Public License for more details.
|
||||
;;;
|
||||
;;; You should have received a copy of the GNU General Public License
|
||||
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
(define-module (commencement)
|
||||
#:use-module (gnu packages)
|
||||
#:use-module (gnu packages bootstrap)
|
||||
#:use-module (gnu packages autotools)
|
||||
#:use-module (gnu packages base)
|
||||
#:use-module (gnu packages bash)
|
||||
#:use-module (gnu packages c)
|
||||
#:use-module (gnu packages gcc)
|
||||
#:use-module (gnu packages m4)
|
||||
#:use-module (gnu packages gawk)
|
||||
#:use-module (gnu packages bison)
|
||||
#:use-module (gnu packages flex)
|
||||
#:use-module (gnu packages guile)
|
||||
#:use-module (gnu packages gettext)
|
||||
#:use-module (gnu packages multiprecision)
|
||||
#:use-module (gnu packages compression)
|
||||
#:use-module (gnu packages mes)
|
||||
#:use-module (gnu packages perl)
|
||||
#:use-module (gnu packages python)
|
||||
#:use-module (gnu packages linux)
|
||||
#:use-module (gnu packages hurd)
|
||||
#:use-module (gnu packages shells)
|
||||
#:use-module (gnu packages texinfo)
|
||||
#:use-module (gnu packages pkg-config)
|
||||
#:use-module (gnu packages xml)
|
||||
#:use-module (guix gexp)
|
||||
#:use-module (guix packages)
|
||||
#:use-module ((guix store) #:select (%store-monad))
|
||||
#:use-module (guix monads)
|
||||
#:use-module (guix download)
|
||||
#:use-module (guix git-download)
|
||||
#:use-module (guix build-system gnu)
|
||||
#:use-module (guix build-system trivial)
|
||||
#:use-module ((guix licenses) #:prefix license:)
|
||||
#:use-module (guix memoization)
|
||||
#:use-module (guix utils)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (ice-9 popen)
|
||||
#:use-module (ice-9 rdelim)
|
||||
#:use-module (ice-9 vlist)
|
||||
#:use-module (ice-9 match)
|
||||
#:export (make-gcc-toolchain))
|
||||
|
||||
;;; Commentary:
|
||||
;;;
|
||||
;;; This is the commencement, this is where things start. Before the
|
||||
;;; commencement, of course, there's the 'bootstrap' module, which provides us
|
||||
;;; with the initial binaries. This module uses those bootstrap binaries to
|
||||
;;; actually build up the whole tool chain that make up the implicit inputs of
|
||||
;;; 'gnu-build-system'.
|
||||
;;;
|
||||
;;; To avoid circular dependencies, this module should not be imported
|
||||
;;; directly from anywhere.
|
||||
;;;
|
||||
;;; Below, we frequently use "inherit" to create modified packages. The
|
||||
;;; reason why we use "inherit" instead of "package/inherit" is because we do
|
||||
;;; not want these commencement packages to inherit grafts. By definition,
|
||||
;;; these packages are not depended on at run time by any of the packages we
|
||||
;;; use. Thus it does not make sense to inherit grafts. Furthermore, those
|
||||
;;; grafts would often lead to extra overhead for users who would end up
|
||||
;;; downloading those "-boot0" packages just to build package replacements
|
||||
;;; that are in fact not going to be used.
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(define* (git-fetch-from-tarball tarball)
|
||||
"Return an <origin> method equivalent to 'git-fetch', except that it fetches
|
||||
the checkout from TARBALL, a tarball containing said checkout.
|
||||
|
||||
The purpose of this procedure is to work around bootstrapping issues:
|
||||
'git-fetch' depends on Git, which is much higher in the dependency graph."
|
||||
(lambda* (url hash-algo hash
|
||||
#:optional name
|
||||
#:key (system (%current-system))
|
||||
(guile %bootstrap-guile))
|
||||
(mlet %store-monad ((guile (package->derivation guile system)))
|
||||
(gexp->derivation
|
||||
(or name "git-checkout")
|
||||
(with-imported-modules '((guix build utils))
|
||||
#~(begin
|
||||
(use-modules (guix build utils)
|
||||
(ice-9 ftw)
|
||||
(ice-9 match))
|
||||
(setenv "PATH"
|
||||
#+(file-append %bootstrap-coreutils&co "/bin"))
|
||||
(invoke "tar" "xf" #$tarball)
|
||||
(match (scandir ".")
|
||||
(("." ".." directory)
|
||||
(copy-recursively directory #$output)))))
|
||||
#:recursive? #t
|
||||
#:hash-algo hash-algo
|
||||
#:hash hash
|
||||
#:system system
|
||||
#:guile-for-build guile
|
||||
#:graft? #f
|
||||
#:local-build? #t))))
|
||||
|
||||
(define bootar
|
||||
(package
|
||||
(name "bootar")
|
||||
(version "1b")
|
||||
(source (origin
|
||||
(method url-fetch)
|
||||
(uri (list (string-append
|
||||
"mirror://gnu/guix/mirror/bootar-" version ".ses")
|
||||
(string-append
|
||||
"https://files.ngyro.com/bootar/bootar-"
|
||||
version ".ses")))
|
||||
(sha256
|
||||
(base32
|
||||
"0cf5vj5yxfvkgzvjvh2l7b2nz5ji5l534n9g4mfp8f5jsjqdrqjc"))))
|
||||
(build-system gnu-build-system)
|
||||
(arguments
|
||||
`(#:implicit-inputs? #f
|
||||
#:tests? #f
|
||||
#:guile ,%bootstrap-guile
|
||||
#:imported-modules ((guix build gnu-bootstrap)
|
||||
,@%gnu-build-system-modules)
|
||||
#:phases
|
||||
(begin
|
||||
(use-modules (guix build gnu-bootstrap))
|
||||
(modify-phases %standard-phases
|
||||
(replace 'unpack
|
||||
(lambda* (#:key inputs #:allow-other-keys)
|
||||
(let* ((source (assoc-ref inputs "source"))
|
||||
(guile-dir (assoc-ref inputs "guile"))
|
||||
(guile (string-append guile-dir "/bin/guile")))
|
||||
(invoke guile "--no-auto-compile" source)
|
||||
(chdir "bootar"))))
|
||||
(replace 'configure (bootstrap-configure "Bootar" ,version
|
||||
'(".") "scripts"))
|
||||
(replace 'build (bootstrap-build '(".")))
|
||||
(replace 'install (bootstrap-install '(".") "scripts"))))))
|
||||
(inputs `(("guile" ,%bootstrap-guile)))
|
||||
(home-page "https://git.ngyro.com/bootar")
|
||||
(synopsis "Tar decompression and extraction in Guile Scheme")
|
||||
(description "Bootar is a simple Tar extractor written in Guile
|
||||
Scheme. It supports running 'tar xvf' on uncompressed tarballs or
|
||||
tarballs that are compressed with BZip2, GZip, or XZ. It also provides
|
||||
standalone scripts for 'bzip2', 'gzip', and 'xz' that each support
|
||||
decompression to standard output.
|
||||
|
||||
What makes this special is that Bootar is distributed as a
|
||||
self-extracting Scheme (SES) program. That is, a little script that
|
||||
outputs the source code of Bootar. This makes it possible to go from
|
||||
pure Scheme to Tar and decompression in one easy step.")
|
||||
(license license:gpl3+)))
|
||||
|
||||
(define gash-boot
|
||||
(package
|
||||
(inherit gash)
|
||||
(name "gash-boot")
|
||||
(arguments
|
||||
`(#:implicit-inputs? #f
|
||||
#:tests? #f
|
||||
#:guile ,%bootstrap-guile
|
||||
#:imported-modules ((guix build gnu-bootstrap)
|
||||
,@%gnu-build-system-modules)
|
||||
#:phases
|
||||
(begin
|
||||
(use-modules (guix build gnu-bootstrap))
|
||||
(modify-phases %standard-phases
|
||||
(replace 'configure
|
||||
(bootstrap-configure "Gash" ,(package-version gash)
|
||||
'("gash") "scripts"))
|
||||
(replace 'build (bootstrap-build '("gash")))
|
||||
(replace 'install (bootstrap-install '("gash") "scripts"))
|
||||
(add-after 'install 'install-symlinks
|
||||
(lambda* (#:key outputs #:allow-other-keys)
|
||||
(let ((out (assoc-ref outputs "out")))
|
||||
(symlink (string-append out "/bin/gash")
|
||||
(string-append out "/bin/sh"))
|
||||
(symlink (string-append out "/bin/gash")
|
||||
(string-append out "/bin/bash")))))))))
|
||||
(inputs `(("guile" ,%bootstrap-guile)))
|
||||
(native-inputs `(("bootar" ,bootar)))))
|
||||
|
||||
(define gash-utils-boot
|
||||
(package
|
||||
(inherit gash-utils)
|
||||
(name "gash-utils-boot")
|
||||
(arguments
|
||||
`(#:implicit-inputs? #f
|
||||
#:tests? #f
|
||||
#:guile ,%bootstrap-guile
|
||||
#:imported-modules ((guix build gnu-bootstrap)
|
||||
,@%gnu-build-system-modules)
|
||||
#:phases
|
||||
(begin
|
||||
(use-modules (guix build gnu-bootstrap))
|
||||
(modify-phases %standard-phases
|
||||
(add-after 'unpack 'set-load-path
|
||||
(lambda* (#:key inputs #:allow-other-keys)
|
||||
(let ((gash (assoc-ref inputs "gash")))
|
||||
(add-to-load-path (string-append gash "/share/guile/site/"
|
||||
(effective-version))))))
|
||||
(add-before 'configure 'pre-configure
|
||||
(lambda _
|
||||
(format #t "Creating gash/commands/testb.scm~%")
|
||||
(copy-file "gash/commands/test.scm"
|
||||
"gash/commands/testb.scm")
|
||||
(substitute* "gash/commands/testb.scm"
|
||||
(("gash commands test") "gash commands testb")
|
||||
(("apply test [(]cdr") "apply test/bracket (cdr"))
|
||||
(for-each (lambda (script)
|
||||
(let ((target (string-append "scripts/"
|
||||
script ".in")))
|
||||
(format #t "Creating scripts/~a~%" target)
|
||||
(copy-file "scripts/template.in" target)
|
||||
(substitute* target
|
||||
(("@UTILITY@") script))))
|
||||
'("awk" "basename" "cat" "chmod" "cmp" "command"
|
||||
"compress" "cp" "cut" "diff" "dirname" "env"
|
||||
"expr" "false" "find" "grep" "head" "ln" "ls"
|
||||
"mkdir" "mv" "printf" "pwd" "reboot" "rm" "rmdir"
|
||||
"sed" "sleep" "sort" "tar" "test" "touch" "tr"
|
||||
"true" "uname" "uniq" "wc" "which"))
|
||||
(format #t "Creating scripts/[.in~%")
|
||||
(copy-file "scripts/template.in" "scripts/[.in")
|
||||
(substitute* "scripts/[.in"
|
||||
(("@UTILITY@") "testb"))
|
||||
(delete-file "scripts/template.in")))
|
||||
(replace 'configure
|
||||
(bootstrap-configure "Gash-Utils" ,(package-version gash-utils)
|
||||
'("gash" "gash-utils") "scripts"))
|
||||
(replace 'build (bootstrap-build '("gash" "gash-utils")))
|
||||
(replace 'install
|
||||
(bootstrap-install '("gash" "gash-utils") "scripts"))
|
||||
;; XXX: The scripts should add Gash to their load paths and
|
||||
;; this phase should not exist.
|
||||
(add-after 'install 'copy-gash
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(let* ((out (assoc-ref outputs "out"))
|
||||
(moddir (string-append out "/share/guile/site/"
|
||||
(effective-version)))
|
||||
(godir (string-append out "/lib/guile/"
|
||||
(effective-version)
|
||||
"/site-ccache"))
|
||||
(gash (assoc-ref inputs "gash"))
|
||||
(gash-moddir (string-append gash "/share/guile/site/"
|
||||
(effective-version)))
|
||||
(gash-godir (string-append gash "/lib/guile/"
|
||||
(effective-version)
|
||||
"/site-ccache")))
|
||||
(copy-file (string-append gash-moddir "/gash/compat.scm")
|
||||
(string-append moddir "/gash/compat.scm"))
|
||||
(copy-recursively (string-append gash-moddir "/gash/compat")
|
||||
(string-append moddir "/gash/compat"))
|
||||
(copy-file (string-append gash-godir "/gash/compat.go")
|
||||
(string-append godir "/gash/compat.go"))
|
||||
(copy-recursively (string-append gash-godir "/gash/compat")
|
||||
(string-append godir "/gash/compat")))))
|
||||
;; We need an external echo.
|
||||
(add-after 'install 'make-echo
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(let* ((out (assoc-ref outputs "out"))
|
||||
(gash (assoc-ref inputs "gash")))
|
||||
(with-output-to-file (string-append out "/bin/echo")
|
||||
(lambda ()
|
||||
(display (string-append "#!" gash "/bin/gash\n"))
|
||||
(newline)
|
||||
(display "echo \"$@\"")
|
||||
(newline)))
|
||||
(chmod (string-append out "/bin/echo") #o755))))))))
|
||||
(inputs `(("gash" ,gash-boot)
|
||||
("guile" ,%bootstrap-guile)))
|
||||
(native-inputs `(("bootar" ,bootar)))))
|
||||
|
||||
(define (%boot-gash-inputs)
|
||||
`(("bash" , gash-boot) ; gnu-build-system wants "bash"
|
||||
("coreutils" , gash-utils-boot)
|
||||
("bootar" ,bootar)
|
||||
("guile" ,%bootstrap-guile)))
|
||||
|
||||
(define bootstrap-seeds
|
||||
(package
|
||||
(name "bootstrap-seeds")
|
||||
(version "1.0.0")
|
||||
(source (origin
|
||||
(method url-fetch)
|
||||
(uri (list
|
||||
(string-append "mirror://gnu/guix/mirror/"
|
||||
"bootstrap-seeds-" version ".tar.gz")
|
||||
(string-append
|
||||
"https://lilypond.org/janneke/guix/20220501/"
|
||||
"bootstrap-seeds-" version ".tar.gz")))
|
||||
(sha256
|
||||
(base32
|
||||
"0scz2bx8fd8c821h6y1j3x6ywgxxns7iinyn9z32dnkiacfdcpfn"))))
|
||||
(native-inputs (list bootar))
|
||||
(build-system trivial-build-system)
|
||||
(arguments
|
||||
(list #:guile %bootstrap-guile
|
||||
#:modules '((guix build utils))
|
||||
#:builder
|
||||
#~(begin
|
||||
(use-modules (guix build utils))
|
||||
(let ((source #$(package-source this-package))
|
||||
(tar #$(this-package-native-input "bootar"))
|
||||
(out #$output))
|
||||
(setenv "PATH" (string-append tar "/bin:"))
|
||||
(invoke "tar" "xvf" source)
|
||||
(mkdir-p out)
|
||||
(copy-recursively "bootstrap-seeds" out)))))
|
||||
(home-page "https://github.com/oriansj/bootstrap-seeds")
|
||||
(synopsis "The initial bootstrap seeds: 357-byte hex0 and kaem shell")
|
||||
(description
|
||||
"This package provides pre-built binaries of the bootstrap seeds. It
|
||||
contains a hex0-seed and an optional kaem-minimal shell. The size of the hex0
|
||||
seeds are for knight: 250 bytes, x86-linux: 357 bytes, x86_64-linux: 431
|
||||
bytes, and aarch64-linux 526 bytes. These can be used to build stage0: hex0,
|
||||
hex1, hex2, M1, and M2-Planet.")
|
||||
(license license:gpl3+)))
|
||||
|
||||
(define stage0-posix
|
||||
;; The initial bootstrap package: no binary inputs except those from
|
||||
;; `bootstrap-seeds, for x86 a 357 byte binary seed: `x86/hex0-seed'.
|
||||
(package
|
||||
(name "stage0-posix")
|
||||
(version "1.4")
|
||||
(source (origin
|
||||
(method git-fetch)
|
||||
(uri (git-reference
|
||||
(url "https://github.com/oriansj/stage0-posix/")
|
||||
(commit "master")
|
||||
(recursive? #t)))
|
||||
(sha256
|
||||
(base32
|
||||
"0mp0d0q0776571igw62j9hvqy4lq9gb5819wanw0hxi8pyhsk3z6"))))
|
||||
(supported-systems '("i686-linux" "x86_64-linux"
|
||||
"aarch64-linux"
|
||||
"riscv64-linux"))
|
||||
(native-inputs
|
||||
`(("bootstrap-seeds" ,bootstrap-seeds)
|
||||
,@(%boot-gash-inputs)))
|
||||
(build-system trivial-build-system)
|
||||
(arguments
|
||||
(list
|
||||
#:guile %bootstrap-guile
|
||||
#:modules '((guix build utils))
|
||||
#:builder
|
||||
#~(begin
|
||||
(use-modules (guix build utils))
|
||||
(let* ((bootstrap-seeds #$(this-package-native-input
|
||||
"bootstrap-seeds"))
|
||||
(source #$(package-source this-package))
|
||||
(tar #$(this-package-native-input "bootar"))
|
||||
(bash #$(this-package-native-input "bash"))
|
||||
(coreutils #$(this-package-native-input "coreutils"))
|
||||
(guile #$(this-package-input "guile"))
|
||||
(out #$output)
|
||||
(bindir (string-append out "/bin"))
|
||||
(target (or #$(%current-target-system)
|
||||
#$(%current-system)))
|
||||
(stage0-cpu
|
||||
(cond
|
||||
((or #$(target-x86-64?) #$(target-x86-32?))
|
||||
"x86")
|
||||
(#$(target-aarch64?)
|
||||
"AArch64")
|
||||
(#$(target-riscv64?)
|
||||
"riscv64")
|
||||
(else
|
||||
(error "stage0-posix: system not supported" target))))
|
||||
(kaem (string-append "bootstrap-seeds/POSIX/"
|
||||
stage0-cpu "/kaem-optional-seed")))
|
||||
(setenv "PATH" (string-append tar "/bin:"
|
||||
coreutils "/bin:"
|
||||
bash "/bin"))
|
||||
(copy-recursively source "stage0-posix")
|
||||
(chdir "stage0-posix")
|
||||
(invoke kaem (string-append "kaem." stage0-cpu))
|
||||
(with-directory-excursion (string-append stage0-cpu "/bin")
|
||||
(install-file "hex2" bindir)
|
||||
(install-file "M1" bindir)
|
||||
(install-file "blood-elf" bindir)
|
||||
(install-file "kaem" bindir)
|
||||
(install-file "get_machine" bindir)
|
||||
(install-file "M2-Planet" bindir))))))
|
||||
(home-page "https://github.com/oriansj/stage0-posix/")
|
||||
(synopsis "The initial bootstrap package, builds stage0 up to M2-Planet")
|
||||
(description "Starting from the 357-byte hex0-seed binary provided by
|
||||
the bootstrap-seeds, the stage0-posix package first builds hex0 and then all
|
||||
the way up: hex1, catm, hex2, M0, cc_x86, M1, M2, get_machine (that's all of
|
||||
MesCC-Tools), and finally M2-Planet.")
|
||||
(license license:gpl3+)))
|
||||
|
||||
(define mes-boot
|
||||
(package
|
||||
(inherit mes)
|
||||
(name "mes-boot")
|
||||
(version "0.24.2")
|
||||
(source (origin
|
||||
(method git-fetch)
|
||||
(uri (git-reference
|
||||
(url "https://github.com/ekaitz-zarraga/mes/")
|
||||
(commit "wip-riscv")))
|
||||
(file-name (git-file-name name version))
|
||||
(sha256
|
||||
(base32
|
||||
"19wkdwqh1bsd1hz3ip2w5q7nnkkddcbpr4cmwh81d95q8zf60rm1"))))
|
||||
(inputs '())
|
||||
(propagated-inputs '())
|
||||
(supported-systems '("i686-linux" "x86_64-linux" "riscv64-linux"))
|
||||
(native-inputs
|
||||
`(("m2-planet" ,stage0-posix)
|
||||
("nyacc-source" ,(bootstrap-origin
|
||||
(origin (inherit (package-source nyacc-1.00.2))
|
||||
(snippet #f))))
|
||||
,@(%boot-gash-inputs)))
|
||||
(arguments
|
||||
(list
|
||||
#:implicit-inputs? #f
|
||||
#:tests? #f
|
||||
#:guile %bootstrap-guile
|
||||
#:strip-binaries? #f ;no strip yet
|
||||
#:phases
|
||||
#~(modify-phases %standard-phases
|
||||
(add-after 'unpack 'unpack-seeds
|
||||
(lambda _
|
||||
(let ((nyacc-source #$(this-package-native-input "nyacc-source")))
|
||||
(with-directory-excursion ".."
|
||||
(invoke "tar" "-xvf" nyacc-source)))))
|
||||
(replace 'configure
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(let ((out #$output)
|
||||
(gash #$(this-package-native-input "bash"))
|
||||
(dir (with-directory-excursion ".." (getcwd))))
|
||||
(setenv "GUILE_LOAD_PATH" (string-append
|
||||
dir "/nyacc-1.00.2/module"))
|
||||
(invoke "gash" "configure.sh"
|
||||
(string-append "--prefix=" out)
|
||||
"--host=riscv64-linux-gnu"))))
|
||||
(replace 'build
|
||||
(lambda _
|
||||
(invoke "gash" "bootstrap.sh")))
|
||||
(delete 'check)
|
||||
(replace 'install
|
||||
(lambda* (#:key outputs #:allow-other-keys)
|
||||
(substitute* "install.sh" ; show some progress
|
||||
((" -xf") " -xvf")
|
||||
(("^( *)((cp|mkdir|tar) [^']*[^\\])\n" all space cmd)
|
||||
(string-append space "echo '" cmd "'\n"
|
||||
space cmd "\n")))
|
||||
(invoke "gash" "install.sh")
|
||||
;; Keep ASCII output, for friendlier comparison and bisection
|
||||
(let* ((out #$output)
|
||||
(cache (string-append out "/lib/cache")))
|
||||
(define (objects-in-dir dir)
|
||||
(find-files dir
|
||||
(lambda (name stat)
|
||||
(and (equal? (dirname name) dir)
|
||||
(or (string-suffix? ".M1" name)
|
||||
(string-suffix? ".hex2" name)
|
||||
(string-suffix? ".o" name)
|
||||
(string-suffix? ".s" name))))))
|
||||
(for-each (lambda (x) (install-file x cache))
|
||||
(append (objects-in-dir "m2")
|
||||
(objects-in-dir ".")
|
||||
(objects-in-dir "mescc-lib")))))))))
|
||||
(native-search-paths
|
||||
(list (search-path-specification
|
||||
(variable "C_INCLUDE_PATH")
|
||||
(files '("include")))
|
||||
(search-path-specification
|
||||
(variable "LIBRARY_PATH")
|
||||
(files '("lib")))
|
||||
(search-path-specification
|
||||
(variable "MES_PREFIX")
|
||||
(separator #f)
|
||||
(files '("")))))))
|
||||
|
||||
|
||||
|
||||
(define %source-dir-this (dirname (dirname (current-filename))))
|
||||
|
||||
(define %git-commit
|
||||
(read-line
|
||||
(open-pipe "git show HEAD | head -1 | cut -d ' ' -f 2 " OPEN_READ)))
|
||||
|
||||
(define (discard-git path stat)
|
||||
(let* ((start (1+ (string-length %source-dir-this)) )
|
||||
(end (+ 4 start)))
|
||||
(not (false-if-exception (equal? ".git" (substring path start end))))))
|
||||
|
||||
(define-public tcc-boot0
|
||||
;; Pristine tcc cannot be built by MesCC, we are keeping a delta of 30
|
||||
;; patches. In a very early and rough form they were presented to the
|
||||
;; TinyCC developers, who at the time showed no interest in supporting the
|
||||
;; bootstrappable effort; we will try again later. These patches have been
|
||||
;; ported to 0.9.27, alas the resulting tcc is buggy. Once MesCC is more
|
||||
;; mature, this package should use the 0.9.27 sources (or later).
|
||||
;;
|
||||
;;
|
||||
;; TODO: Read and adjust configure.sh and boostrap.sh...
|
||||
(package
|
||||
(inherit tcc)
|
||||
(name "tcc-boot0")
|
||||
(version "0.9.26-1136-g5bba73cc")
|
||||
(source (origin
|
||||
(method url-fetch)
|
||||
(uri (list
|
||||
(string-append "mirror://gnu/guix/mirror/"
|
||||
"tcc-" version ".tar.gz")
|
||||
(string-append "https://lilypond.org/janneke/tcc/"
|
||||
"tcc-" version ".tar.gz")))
|
||||
(sha256
|
||||
(base32
|
||||
"1y2f04qwdqg7dgxiscbf0ibybx2gclniwbbcsxpayazzii2cvji3"))))
|
||||
|
||||
|
||||
(source (local-file %source-dir-this
|
||||
#:recursive? #t
|
||||
#:select? discard-git))
|
||||
(build-system gnu-build-system)
|
||||
(supported-systems '("i686-linux" "x86_64-linux" "riscv64-linux"))
|
||||
(inputs '())
|
||||
(propagated-inputs '())
|
||||
(native-inputs
|
||||
`(("mes" ,mes-boot)
|
||||
("mescc-tools" ,stage0-posix)
|
||||
("nyacc-source" ,(bootstrap-origin
|
||||
(origin (inherit (package-source nyacc-1.00.2))
|
||||
(snippet #f))))
|
||||
,@(%boot-gash-inputs)))
|
||||
(arguments
|
||||
(list
|
||||
#:implicit-inputs? #f
|
||||
#:guile %bootstrap-guile
|
||||
#:validate-runpath? #f ; no dynamic executables
|
||||
#:strip-binaries? #f ; no strip yet
|
||||
#:phases
|
||||
#~(modify-phases %standard-phases
|
||||
(add-after 'unpack 'unpack-extra-sources
|
||||
(lambda* (#:key outputs #:allow-other-keys)
|
||||
(let ((nyacc-source #$(this-package-native-input "nyacc-source")))
|
||||
(with-directory-excursion ".."
|
||||
(invoke "tar" "-xvf" nyacc-source)))))
|
||||
(replace 'configure
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(let* ((out #$output)
|
||||
(dir (with-directory-excursion ".." (getcwd)))
|
||||
(interpreter "/lib/mes-loader")
|
||||
(mes #$(this-package-native-input "mes"))
|
||||
(mescc (string-append mes "/bin/mescc")))
|
||||
(substitute* "conftest.c"
|
||||
(("volatile") ""))
|
||||
(setenv "prefix" out)
|
||||
(setenv "GUILE_LOAD_PATH"
|
||||
(string-append dir "/nyacc-1.00.2/module"))
|
||||
(invoke "sh" "configure"
|
||||
"--cc=mescc"
|
||||
(string-append "--prefix=" out)
|
||||
(string-append "--elfinterp=" interpreter)
|
||||
"--crtprefix=."
|
||||
"--tccdir=."))))
|
||||
(replace 'build
|
||||
(lambda _
|
||||
(setenv "V" "2")
|
||||
(substitute* "bootstrap.sh" ; Show some progress
|
||||
(("^( *)((cp|ls|mkdir|rm|[.]/tcc|[.]/[$][{program_prefix[}]tcc) [^\"]*[^\\])\n" all space cmd)
|
||||
(string-append space "echo \"" cmd "\"\n"
|
||||
space cmd "\n")))
|
||||
(invoke "sh" "bootstrap.sh")))
|
||||
(replace 'check
|
||||
(lambda _
|
||||
;; fail fast tests
|
||||
(system* "./tcc" "--help") ; --help exits 1
|
||||
;; (invoke "sh" "test.sh" "mes/scaffold/tests/30-strlen")
|
||||
;; (invoke "sh" "-x" "test.sh" "mes/scaffold/tinycc/00_assignment")
|
||||
;; TODO: add sensible check target (without depending on make)
|
||||
;; (invoke "sh" "check.sh")
|
||||
))
|
||||
(replace 'install
|
||||
(lambda _
|
||||
(substitute* "install.sh" ; Show some progress
|
||||
(("^( *)((cp|ls|mkdir|rm|tar|./[$][{PROGRAM_PREFIX[}]tcc) [^\"]*[^\\])\n" all space cmd)
|
||||
(string-append space "echo \"" cmd "\"\n"
|
||||
space cmd "\n")))
|
||||
|
||||
(invoke "sh" "install.sh"))))))
|
||||
(native-search-paths
|
||||
(list (search-path-specification
|
||||
(variable "C_INCLUDE_PATH")
|
||||
(files '("include")))
|
||||
(search-path-specification
|
||||
(variable "LIBRARY_PATH")
|
||||
(files '("lib")))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
tcc-boot0
|
|
@ -0,0 +1 @@
|
|||
manifest_riscv.scm
|
|
@ -0,0 +1,13 @@
|
|||
(load "package_i386.scm")
|
||||
(use-modules (gnu packages gdb))
|
||||
(define triplet "i686-linux-gnu")
|
||||
|
||||
(packages->manifest
|
||||
(let* ((binutils (cross-binutils triplet))
|
||||
(libc (cross-libc triplet)))
|
||||
(list tcc-mine-i386
|
||||
(list gcc "lib")
|
||||
binutils
|
||||
libc
|
||||
gdb
|
||||
(list libc "static"))))
|
|
@ -0,0 +1,13 @@
|
|||
(load "package_riscv.scm")
|
||||
(use-modules (gnu packages gdb))
|
||||
(define triplet "riscv64-linux-gnu")
|
||||
|
||||
(packages->manifest
|
||||
(let* ((binutils (cross-binutils triplet))
|
||||
(libc (cross-libc triplet)))
|
||||
(list tcc-mine-riscv
|
||||
(list gcc "lib")
|
||||
binutils
|
||||
libc
|
||||
gdb
|
||||
(list libc "static"))))
|
|
@ -0,0 +1,111 @@
|
|||
(use-modules (ice-9 popen)
|
||||
(ice-9 rdelim)
|
||||
(guix packages)
|
||||
(guix utils)
|
||||
(guix gexp)
|
||||
(guix profiles)
|
||||
(guix download)
|
||||
(guix build-system gnu)
|
||||
((guix licenses) #:prefix license:)
|
||||
(gnu packages gcc)
|
||||
(gnu packages base)
|
||||
(gnu packages linux)
|
||||
(gnu packages maths)
|
||||
(gnu packages perl)
|
||||
(gnu packages cross-base)
|
||||
(gnu packages bootstrap)
|
||||
(gnu packages texinfo))
|
||||
|
||||
(define %source-dir (dirname (dirname (current-filename))))
|
||||
|
||||
(define %git-commit
|
||||
(read-line
|
||||
(open-pipe "git show HEAD | head -1 | cut -d ' ' -f 2 " OPEN_READ)))
|
||||
|
||||
(define (discard-git path stat)
|
||||
(let* ((start (1+ (string-length %source-dir)) )
|
||||
(end (+ 4 start)))
|
||||
(not (false-if-exception (equal? ".git" (substring path start end))))))
|
||||
|
||||
(define libccross (cross-libc "riscv64-linux-gnu"))
|
||||
(define libccross-i386 (cross-libc "i686-linux-gnu"))
|
||||
|
||||
(define-public tcc-mine-i386
|
||||
(package
|
||||
(name "tcc") ;aka. "tinycc"
|
||||
(version "i386-mes-HEAD")
|
||||
(source (local-file %source-dir
|
||||
#:recursive? #t
|
||||
#:select? discard-git))
|
||||
(build-system gnu-build-system)
|
||||
(native-inputs (list perl texinfo which))
|
||||
(arguments
|
||||
(list
|
||||
#:configure-flags
|
||||
#~(list "--enable-cross"
|
||||
"--disable-rpath"
|
||||
"--extra-cflags=-DHAVE_FLOAT=1 -DHAVE_BITFIELD=1 -DHAVE_LONG_LONG=1 -DHAVE_SETJMP=1 -DASM_DEBUG=1")
|
||||
#:tests? #f
|
||||
#:validate-runpath? #f
|
||||
#:phases #~(modify-phases %standard-phases
|
||||
(replace 'build
|
||||
(lambda _
|
||||
(invoke "make" "cross-i386")))
|
||||
|
||||
;; Cross compilers don't get the default config so we need to add custom
|
||||
;; configuration like explained in `make help`
|
||||
(add-before 'configure 'configure-cross
|
||||
(lambda _
|
||||
(call-with-output-file "config-cross.mak"
|
||||
(lambda (port)
|
||||
(display
|
||||
(string-append "CRT-i386 = " #$libccross-i386 "/lib") port)
|
||||
(newline port)
|
||||
(display
|
||||
(string-append "LIB-i386 = " #$libccross-i386 "/lib") port)
|
||||
(newline port)
|
||||
(display
|
||||
(string-append "INC-i386 = " #$libccross-i386 "/include" ":" #$output "/include") port)))))
|
||||
|
||||
;(add-before 'install 'fail (lambda _ (error "Fail for debug")))
|
||||
|
||||
;; Default `make install` phase does not install the cross compilers
|
||||
;; We have to do it by hand
|
||||
(replace 'install
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
;; Make an empty libtcc1. Needed because:
|
||||
;; - Later it'll try to dynamically link it (needed)
|
||||
;; - It only has i386 related definitions, and fails if it's compiled in other arch (make it empty)
|
||||
(call-with-output-file "lib/libtcc1.c"
|
||||
(lambda (p) (display "" p)))
|
||||
(invoke "./i386-tcc" "-c" "lib/libtcc1.c" "-o" "libtcc1.o")
|
||||
(invoke "./i386-tcc" "-ar" "cr" "libtcc1-i386.a" "libtcc1.o")
|
||||
|
||||
;; Now install
|
||||
(install-file "libtcc1-i386.a"
|
||||
(string-append (assoc-ref outputs "out") "/lib/tcc"))
|
||||
(install-file "i386-tcc"
|
||||
(string-append (assoc-ref outputs "out") "/bin"))
|
||||
(copy-recursively "include"
|
||||
(string-append (assoc-ref outputs "out") "/include")))))))
|
||||
(native-search-paths
|
||||
(list (search-path-specification
|
||||
(variable "CPATH")
|
||||
(files '("include")))
|
||||
(search-path-specification
|
||||
(variable "LIBRARY_PATH")
|
||||
(files '("lib" "lib64")))))
|
||||
|
||||
(outputs (list "out" "debug"))
|
||||
(synopsis "Tiny and fast C compiler")
|
||||
(description
|
||||
"TCC, also referred to as \"TinyCC\", is a small and fast C compiler
|
||||
written in C. It supports ANSI C with GNU and extensions and most of the C99
|
||||
standard.")
|
||||
(home-page "http://www.tinycc.org/")
|
||||
;; An attempt to re-licence tcc under the Expat licence is underway but not
|
||||
;; (if ever) complete. See the RELICENSING file for more information.
|
||||
(license license:lgpl2.1+)))
|
||||
|
||||
|
||||
tcc-mine-i386
|
|
@ -0,0 +1,113 @@
|
|||
(use-modules (ice-9 popen)
|
||||
(ice-9 rdelim)
|
||||
(guix packages)
|
||||
(guix utils)
|
||||
(guix gexp)
|
||||
(guix profiles)
|
||||
(guix download)
|
||||
(guix build-system gnu)
|
||||
((guix licenses) #:prefix license:)
|
||||
(gnu packages gcc)
|
||||
(gnu packages base)
|
||||
(gnu packages linux)
|
||||
(gnu packages maths)
|
||||
(gnu packages perl)
|
||||
(gnu packages cross-base)
|
||||
(gnu packages bootstrap)
|
||||
(gnu packages texinfo))
|
||||
|
||||
(define %source-dir (dirname (dirname (current-filename))))
|
||||
|
||||
(define %git-commit
|
||||
(read-line
|
||||
(open-pipe "git show HEAD | head -1 | cut -d ' ' -f 2 " OPEN_READ)))
|
||||
|
||||
(define (discard-git path stat)
|
||||
(let* ((start (1+ (string-length %source-dir)) )
|
||||
(end (+ 4 start)))
|
||||
(not (false-if-exception (equal? ".git" (substring path start end))))))
|
||||
|
||||
(define libccross (cross-libc "riscv64-linux-gnu"))
|
||||
(define libccross-i386 (cross-libc "i686-linux-gnu"))
|
||||
|
||||
(define-public tcc-mine-riscv
|
||||
(package
|
||||
(name "tcc") ;aka. "tinycc"
|
||||
(version "riscv-mes-HEAD")
|
||||
(source (local-file %source-dir
|
||||
#:recursive? #t
|
||||
#:select? discard-git))
|
||||
(build-system gnu-build-system)
|
||||
(native-inputs (list perl texinfo which))
|
||||
(arguments
|
||||
(list
|
||||
#:configure-flags
|
||||
#~(list "--enable-cross"
|
||||
"--disable-rpath"
|
||||
(string-append "--extra-cflags="
|
||||
"-DHAVE_FLOAT=1 "
|
||||
"-DHAVE_BITFIELD=1 "
|
||||
"-DHAVE_LONG_LONG=1 "
|
||||
"-DHAVE_SETJMP=1 "
|
||||
"-DASM_DEBUG=1 "
|
||||
"-DCONFIG_TCC_ELFINTERP=\\\\\"\\\"" #$libccross "/lib/ld-linux-riscv64-lp64d.so.1\\\\\"\\\""))
|
||||
#:tests? #f
|
||||
#:validate-runpath? #f
|
||||
#:phases #~(modify-phases %standard-phases
|
||||
(replace 'build
|
||||
(lambda _
|
||||
(invoke "make" "cross-riscv64")))
|
||||
|
||||
;; Cross compilers don't get the default config so we need to add custom
|
||||
;; configuration like explained in `make help`
|
||||
(add-before 'configure 'configure-cross
|
||||
(lambda _
|
||||
(call-with-output-file "config-cross.mak"
|
||||
(lambda (port)
|
||||
(display
|
||||
(string-append "CRT-riscv64 = " #$libccross "/lib") port)
|
||||
(newline port)
|
||||
(display
|
||||
(string-append "LIB-riscv64 = " #$libccross "/lib") port)
|
||||
(newline port)
|
||||
(display
|
||||
(string-append "INC-riscv64 = " #$libccross "/include" ":" #$output "/include") port)))))
|
||||
|
||||
;; Use lib/lib-arm64.c. Needed for long-double support.
|
||||
;; - Later it'll try to link it (needed)
|
||||
(add-before 'install 'build-libtcc1
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(invoke "./riscv64-tcc" "-c" "lib/lib-arm64.c" "-o" "libtcc1.o")
|
||||
(invoke "./riscv64-tcc" "-ar" "cr" "libtcc1-riscv64.a" "libtcc1.o")))
|
||||
|
||||
;; Default `make install` phase does not install the cross compilers
|
||||
;; We have to do it by hand
|
||||
(replace 'install
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(install-file "libtcc1-riscv64.a"
|
||||
(string-append (assoc-ref outputs "out") "/lib/tcc"))
|
||||
(install-file "riscv64-tcc"
|
||||
(string-append (assoc-ref outputs "out") "/bin"))
|
||||
(copy-recursively "include"
|
||||
(string-append (assoc-ref outputs "out") "/include")))))))
|
||||
(native-search-paths
|
||||
(list (search-path-specification
|
||||
(variable "CPATH")
|
||||
(files '("include")))
|
||||
(search-path-specification
|
||||
(variable "LIBRARY_PATH")
|
||||
(files '("lib" "lib64")))))
|
||||
|
||||
(outputs (list "out" "debug"))
|
||||
(synopsis "Tiny and fast C compiler")
|
||||
(description
|
||||
"TCC, also referred to as \"TinyCC\", is a small and fast C compiler
|
||||
written in C. It supports ANSI C with GNU and extensions and most of the C99
|
||||
standard.")
|
||||
(home-page "http://www.tinycc.org/")
|
||||
;; An attempt to re-licence tcc under the Expat licence is underway but not
|
||||
;; (if ever) complete. See the RELICENSING file for more information.
|
||||
(license license:lgpl2.1+)))
|
||||
|
||||
|
||||
tcc-mine-riscv
|
|
@ -0,0 +1,160 @@
|
|||
(use-modules (ice-9 popen)
|
||||
(ice-9 rdelim)
|
||||
(guix packages)
|
||||
(guix utils)
|
||||
(guix gexp)
|
||||
(guix profiles)
|
||||
(guix download)
|
||||
(guix build-system gnu)
|
||||
((guix licenses) #:prefix license:)
|
||||
(gnu packages c)
|
||||
(gnu packages guile)
|
||||
(gnu packages cross-base)
|
||||
(gnu packages base)
|
||||
(gnu packages linux)
|
||||
(gnu packages maths)
|
||||
(gnu packages perl)
|
||||
(gnu packages cross-base)
|
||||
(gnu packages bootstrap)
|
||||
(gnu packages texinfo))
|
||||
|
||||
(define %source-dir-this (dirname (dirname (current-filename))))
|
||||
|
||||
(define %git-commit
|
||||
(read-line
|
||||
(open-pipe "git show HEAD | head -1 | cut -d ' ' -f 2 " OPEN_READ)))
|
||||
|
||||
(define (discard-git path stat)
|
||||
(let* ((start (1+ (string-length %source-dir-this)) )
|
||||
(end (+ 4 start)))
|
||||
(not (false-if-exception (equal? ".git" (substring path start end))))))
|
||||
|
||||
;; From mes source
|
||||
;; NOTE: It expects Mes to be in a folder adjacent to the tcc project folder
|
||||
(define %source-dir-mes (string-append (dirname (dirname (dirname (current-filename)))) "/mes/guix.scm"))
|
||||
(chdir (dirname %source-dir-mes))
|
||||
(load %source-dir-mes)
|
||||
(chdir %source-dir-this)
|
||||
|
||||
(package
|
||||
(name "tcc-MES")
|
||||
(version "0.0.1")
|
||||
(source (local-file %source-dir-this
|
||||
#:recursive? #t
|
||||
#:select? discard-git))
|
||||
(build-system gnu-build-system)
|
||||
(inputs '())
|
||||
(propagated-inputs '())
|
||||
(native-inputs (list mes.git mescc-tools nyacc guile-3.0))
|
||||
|
||||
(arguments
|
||||
(list
|
||||
#:validate-runpath? #f
|
||||
#:phases
|
||||
#~(modify-phases %standard-phases
|
||||
;(add-before 'configure 'fail (lambda _ (error ":)"))
|
||||
(add-before 'configure 'conftest
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(substitute* "conftest.c"
|
||||
(("volatile") ""))))
|
||||
|
||||
;; Uses live-bootstrap as a reference
|
||||
;; https://git.stikonas.eu/andrius/live-bootstrap/src/branch/mes-x86_64/sysa/tcc-0.9.26/tcc-0.9.26.kaem#L62
|
||||
;; TODO: ADD THE CRTS properly
|
||||
(replace 'configure
|
||||
(lambda _
|
||||
(let ((target-system (or #$(%current-target-system)
|
||||
#$(%current-system))))
|
||||
;; TODO: set other variables
|
||||
(setenv "MES" "guile") ; This literally reduces build times x20
|
||||
(setenv "MES_STACK" "15000000")
|
||||
(setenv "MES_ARENA" "30000000")
|
||||
(setenv "MES_MAX_ARENA" "30000000")
|
||||
(setenv "MES_LIB" (string-append #$mes.git "/lib"))
|
||||
(cond
|
||||
((string-prefix? "x86_64-linux" target-system)
|
||||
(begin
|
||||
(display "Preparing for x86_64-linux...\n")
|
||||
(setenv "MES_ARCH" "x86_64")
|
||||
(setenv "TCC_TARGET_ARCH" "X86_64")
|
||||
(setenv "MES_LIBC_SUFFIX" "gcc")))
|
||||
((string-prefix? "aarch64-linux" target-system)
|
||||
(begin
|
||||
(display "Preparing for aarch64-linux...\n")
|
||||
(error "Not supported")))
|
||||
((string-prefix? "riscv64-linux" target-system)
|
||||
(begin
|
||||
(display "Preparing for riscv64-linux...\n")
|
||||
(setenv "MES_ARCH" "riscv64")
|
||||
(setenv "TCC_TARGET_ARCH" "RISCV64")
|
||||
(setenv "MES_LIBC_SUFFIX" "tcc")))
|
||||
(else (error "NO architecture matched\n"))))))
|
||||
|
||||
(replace 'build
|
||||
(lambda _
|
||||
(define-syntax invoke-and-show
|
||||
(syntax-rules (invoke-and-show)
|
||||
((invoke-and-show expr ...)
|
||||
(begin
|
||||
(display (string-join (list "INVOKING: " expr ...) " ") (current-error-port))
|
||||
(force-output (current-error-port))
|
||||
(invoke expr ...)))))
|
||||
|
||||
(invoke-and-show
|
||||
(string-append #$mes.git "/bin/mescc")
|
||||
"-S"
|
||||
"-o" "tcc.s"
|
||||
(string-append "-I" #$mes.git "/include")
|
||||
"-DBOOTSTRAP=1"
|
||||
"-DHAVE_LONG_LONG=1"
|
||||
"-I."
|
||||
(string-append "-DTCC_TARGET_" (getenv "TCC_TARGET_ARCH") "=1")
|
||||
"-Dinline="
|
||||
(string-append "-DCONFIG_TCC_CRTPREFIX=\"" #$mes.git "/lib\"")
|
||||
"-DCONFIG_TCC_ELFINTERP=\"/mes/loader\""
|
||||
(string-append "-DCONFIG_TCC_SYSINCLUDEPATHS=\"" #$mes.git "/include:/include\"")
|
||||
(string-append "-DTCC_LIBGCC=\"" #$mes.git "/lib/libc.a\"")
|
||||
"-DCONFIG_TCC_LIBTCC1_MES=0"
|
||||
"-DCONFIG_TCCBOOT=1"
|
||||
"-DCONFIG_TCC_STATIC=1"
|
||||
"-DCONFIG_USE_LIBGCC=1"
|
||||
"-DTCC_MES_LIBC=1"
|
||||
"-DTCC_VERSION=\"0.9.26\""
|
||||
"-DONE_SOURCE=1"
|
||||
"tcc.c")))
|
||||
|
||||
(add-after 'build 'link
|
||||
(lambda _
|
||||
(invoke (string-append #$mes.git "/bin/mescc")
|
||||
"--base-address" "0x08048000"
|
||||
"-o" "mes-tcc"
|
||||
(string-append "-L" #$mes.git "/lib")
|
||||
"tcc.s"
|
||||
"-lc+tcc")))
|
||||
|
||||
;; There's a better way to do this today but...
|
||||
(replace 'install
|
||||
(lambda* (#:key inputs outputs #:allow-other-keys)
|
||||
(chmod "mes-tcc" #o775)
|
||||
(install-file "mes-tcc"
|
||||
(string-append (assoc-ref outputs "out") "/bin/"))))
|
||||
|
||||
(replace 'check
|
||||
(lambda _
|
||||
(system* "./mes-tcc" "--help"))))))
|
||||
|
||||
(native-search-paths
|
||||
(list (search-path-specification
|
||||
(variable "C_INCLUDE_PATH")
|
||||
(files '("include")))
|
||||
(search-path-specification
|
||||
(variable "LIBRARY_PATH")
|
||||
(files '("lib")))))
|
||||
(outputs (list "out" "debug"))
|
||||
(synopsis "Tiny and fast C compiler")
|
||||
(description
|
||||
"TCC, also referred to as \"TinyCC\", is a small and fast C compiler
|
||||
written in C. It supports ANSI C with GNU and extensions and most of the C99
|
||||
standard.")
|
||||
(home-page "http://www.tinycc.org/")
|
||||
(license license:lgpl2.1+))
|
|
@ -19,7 +19,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#define MAX_OPERANDS 3
|
||||
|
||||
|
@ -221,7 +223,11 @@ static const uint8_t segment_prefixes[] = {
|
|||
static const ASMInstr asm_instrs[] = {
|
||||
#define ALT(x) x
|
||||
/* This removes a 0x0f in the second byte */
|
||||
#if HAVE_LONG_LONG
|
||||
#define O(o) ((uint64_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
|
||||
#else
|
||||
#define O(o) ((uint32_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
|
||||
#endif
|
||||
/* This constructs instr_type from opcode, type and group. */
|
||||
#define T(o,i,g) ((i) | ((g) << OPC_GROUP_SHIFT) | ((((o) & 0xff00) == 0x0f00) ? OPC_0F : 0))
|
||||
#define DEF_ASM_OP0(name, opcode)
|
||||
|
|
|
@ -74,7 +74,9 @@ enum {
|
|||
/******************************************************/
|
||||
#else /* ! TARGET_DEFS_ONLY */
|
||||
/******************************************************/
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
/* define to 1/0 to [not] have EBX as 4th register */
|
||||
#define USE_EBX 0
|
||||
|
@ -1041,6 +1043,7 @@ ST_FUNC void gen_cvt_itof(int t)
|
|||
/* convert fp to int 't' type */
|
||||
ST_FUNC void gen_cvt_ftoi(int t)
|
||||
{
|
||||
#if HAVE_FLOAT
|
||||
int bt = vtop->type.t & VT_BTYPE;
|
||||
if (bt == VT_FLOAT)
|
||||
vpush_global_sym(&func_old_type, TOK___fixsfdi);
|
||||
|
@ -1053,6 +1056,7 @@ ST_FUNC void gen_cvt_ftoi(int t)
|
|||
vpushi(0);
|
||||
vtop->r = REG_IRET;
|
||||
vtop->r2 = REG_LRET;
|
||||
#endif // HAVE_FLOAT
|
||||
}
|
||||
|
||||
/* convert from one floating point type to another */
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
|
||||
#else /* !TARGET_DEFS_ONLY */
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
|
||||
relocations, returns -1. */
|
||||
|
|
|
@ -38,6 +38,23 @@
|
|||
#define LDBL_MAX_EXP 16384
|
||||
#define LDBL_MAX 1.18973149535723176502e+4932L
|
||||
#define LDBL_MAX_10_EXP 4932
|
||||
#define DECIMAL_DIG 21
|
||||
|
||||
#elif defined __aarch64__ || defined __riscv
|
||||
/*
|
||||
* Use values from:
|
||||
* gcc -dM -E -xc /dev/null | grep LDBL | sed -e "s/__//g"
|
||||
*/
|
||||
#define LDBL_MANT_DIG 113
|
||||
#define LDBL_DIG 33
|
||||
#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L
|
||||
#define LDBL_MIN_EXP (-16381)
|
||||
#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
|
||||
#define LDBL_MIN_10_EXP (-4931)
|
||||
#define LDBL_MAX_EXP 16384
|
||||
#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L
|
||||
#define LDBL_MAX_EXP 16384
|
||||
#define DECIMAL_DIG 36
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -67,6 +67,25 @@ typedef struct {
|
|||
#define va_end(ap)
|
||||
#define va_copy(dest, src) ((dest) = (src))
|
||||
|
||||
#elif __riscv
|
||||
typedef __builtin_va_list va_list;
|
||||
typedef char *__builtin_va_list;
|
||||
#define __va_reg_size (__riscv_xlen >> 3)
|
||||
#define va_start __builtin_va_start
|
||||
#define va_arg __builtin_va_arg
|
||||
#define va_copy __builtin_va_copy
|
||||
#define va_end __builtin_va_end
|
||||
typedef char *__builtin_va_list;
|
||||
#define _tcc_align(addr,type) (((unsigned long)addr + __alignof__(type) - 1) \
|
||||
& -(__alignof__(type)))
|
||||
#define __builtin_va_arg(ap,type) (*(sizeof(type) > (2*__va_reg_size) ? *(type **)((ap += __va_reg_size) - __va_reg_size) : (ap = (va_list)(_tcc_align(ap,type) + (sizeof(type)+__va_reg_size - 1)& -__va_reg_size), (type *)(ap - ((sizeof(type)+ __va_reg_size - 1)& -__va_reg_size)))))
|
||||
|
||||
#define __builtin_va_end(ap) (void)(ap)
|
||||
#ifndef __builtin_va_copy
|
||||
# define __builtin_va_copy(dest, src) (dest) = (src)
|
||||
#endif
|
||||
|
||||
|
||||
#else /* __i386__ */
|
||||
typedef char *va_list;
|
||||
/* only correct for i386 */
|
||||
|
|
|
@ -13,12 +13,16 @@ typedef __SIZE_TYPE__ uintptr_t;
|
|||
typedef signed char int8_t;
|
||||
typedef signed short int int16_t;
|
||||
typedef signed int int32_t;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef signed long long int int64_t;
|
||||
#endif
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#if HAVE_LONG_LONG
|
||||
typedef unsigned long long int uint64_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void*)0)
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$V" = 1 -o "$V" = 2 ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
aarch*)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
arm*|aarch*)
|
||||
cpu=arm
|
||||
mes_cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-unknown-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
*)
|
||||
cpu=x86
|
||||
mes_cpu=x86
|
||||
tcc_cpu=i386
|
||||
triplet=i686-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
esac
|
||||
|
||||
prefix=${prefix-usr}
|
||||
MES_PREFIX=${MES_PREFIX-mes}
|
||||
|
||||
mkdir -p $prefix/bin
|
||||
cp tcc $prefix/bin
|
||||
tar -C $MES_PREFIX -cf- include | tar -C $prefix -xf-
|
||||
|
||||
mkdir -p $prefix/lib
|
||||
cp crt1.o $prefix/lib/crt1.o
|
||||
cp crti.o $prefix/lib/crti.o
|
||||
cp crtn.o $prefix/lib/crtn.o
|
||||
|
||||
mkdir -p $prefix/lib/tcc
|
||||
cp libc.a $prefix/lib
|
||||
cp libtcc1.a $prefix/lib/tcc
|
||||
if [ $mes_cpu = arm ]; then
|
||||
cp libtcc1-mes.a $prefix/lib/tcc
|
||||
fi
|
||||
|
||||
cp libgetopt.a $prefix/lib
|
||||
|
||||
mkdir -p $prefix/share
|
||||
cp crt1.c $prefix/share
|
||||
cp crti.c $prefix/share
|
||||
cp crtn.c $prefix/share
|
||||
cp libc.c $prefix/share
|
||||
cp libgetopt.c $prefix/share
|
|
@ -41,6 +41,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 = lib-arm64.o
|
||||
WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
|
||||
|
||||
OBJ-i386 = $(I386_O) $(BCHECK_O)
|
||||
|
@ -56,6 +57,7 @@ OBJ-arm-vfp = $(ARM_O)
|
|||
OBJ-arm-eabi = $(ARM_O)
|
||||
OBJ-arm-eabihf = $(ARM_O)
|
||||
OBJ-arm-wince = $(ARM_O) $(WIN_O)
|
||||
OBJ-riscv64 = $(RISCV64_O) $(BCHECK_O)
|
||||
|
||||
$(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
|
||||
$(XAR) rcs $@ $^
|
||||
|
|
|
@ -24,10 +24,12 @@ void *memcpy(void*,void*,__SIZE_TYPE__);
|
|||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifndef __riscv
|
||||
void __clear_cache(void *beg, void *end)
|
||||
{
|
||||
__arm64_clear_cache(beg, end);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint64_t x0, x1;
|
||||
|
|
28
libtcc.c
28
libtcc.c
|
@ -18,7 +18,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
/********************************************************/
|
||||
/* global variables */
|
||||
|
@ -64,6 +66,11 @@ static int nb_states;
|
|||
#include "x86_64-link.c"
|
||||
#include "i386-asm.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
#include "riscv64-gen.c"
|
||||
#include "riscv64-link.c"
|
||||
#include "riscv64-asm.c"
|
||||
#endif
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
#include "tccasm.c"
|
||||
#endif
|
||||
|
@ -627,7 +634,11 @@ static int tcc_compile(TCCState *s1)
|
|||
Sym *define_start;
|
||||
|
||||
define_start = define_stack;
|
||||
#if HAVE_SETJMP
|
||||
if (setjmp(s1->error_jmp_buf) == 0) {
|
||||
#else
|
||||
if (1) {
|
||||
#endif
|
||||
s1->nb_errors = 0;
|
||||
s1->error_set_jmp_enabled = 1;
|
||||
|
||||
|
@ -734,6 +745,9 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||
tcc_state = s;
|
||||
++nb_states;
|
||||
|
||||
#if BOOTSTRAP
|
||||
s->static_link = 1;
|
||||
#endif
|
||||
s->alacarte_link = 1;
|
||||
s->nocommon = 1;
|
||||
s->warn_implicit_function_declaration = 1;
|
||||
|
@ -775,6 +789,8 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||
tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
|
||||
tcc_define_symbol(s, "__STDC_HOSTED__", NULL);
|
||||
|
||||
tcc_define_symbol(s, "__SIZEOF_LONG_LONG__", "8");
|
||||
|
||||
/* target defines */
|
||||
#if defined(TCC_TARGET_I386)
|
||||
tcc_define_symbol(s, "__i386__", NULL);
|
||||
|
@ -782,6 +798,18 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||
tcc_define_symbol(s, "i386", NULL);
|
||||
#elif defined(TCC_TARGET_X86_64)
|
||||
tcc_define_symbol(s, "__x86_64__", NULL);
|
||||
#elif defined(TCC_TARGET_RISCV64)
|
||||
tcc_define_symbol(s, "__riscv", NULL);
|
||||
tcc_define_symbol(s, "__riscv_xlen", "64");
|
||||
tcc_define_symbol(s, "__riscv_flen", "64");
|
||||
tcc_define_symbol(s, "__riscv_div", NULL);
|
||||
tcc_define_symbol(s, "__riscv_mul", NULL);
|
||||
tcc_define_symbol(s, "__riscv_fdiv", NULL);
|
||||
tcc_define_symbol(s, "__riscv_fsqrt", NULL);
|
||||
tcc_define_symbol(s, "__riscv_float_abi_double", NULL);
|
||||
// This should be defined for every target but in riscv <wordsize.h>
|
||||
// uses it to compare against __riscv_xlen, so we really need it.
|
||||
tcc_define_symbol(s, "__SIZEOF_POINTER__", "8");
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
|
||||
tcc_define_symbol(s, "__arm_elf__", NULL);
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
rm -f 1.a 2.a
|
||||
|
||||
MES_PREFIX=${MES_PREFIX-mes}
|
||||
MES_SOURCE=${MES_SOURCE-mes-source}
|
||||
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
aarch*)
|
||||
cpu=arm
|
||||
triplet=arm-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
arm*|aarch*)
|
||||
cpu=arm
|
||||
triplet=arm-unknown-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
*)
|
||||
cpu=x86
|
||||
triplet=i686-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
esac
|
||||
export cpu
|
||||
export cross_prefix
|
||||
export triplet
|
||||
|
||||
c=${1-$MES_PREFIX/scaffold/main}
|
||||
b=scaffold/${c##*/}
|
||||
|
||||
rm -f "$b".mes-gcc-out
|
||||
rm -f "$b".mes-out
|
||||
|
||||
./${cross_prefix}tcc\
|
||||
-static -g -o "$b".mes-gcc-out\
|
||||
-I.\
|
||||
-I $MES_PREFIX/lib\
|
||||
-I $MES_PREFIX/include\
|
||||
"$c".c \
|
||||
2> "$b".mes-gcc-stderr
|
||||
set +e
|
||||
${MES_TCC-./mes-tcc}\
|
||||
-static -g -o "$b".mes-out
|
||||
-I.\
|
||||
-I $MES_PREFIX/lib\
|
||||
-I $MES_PREFIX/include\
|
||||
2> "$b".mes-stderr
|
||||
objdump -d "$b".mes-gcc-out > "$b".mes-gcc-d
|
||||
objdump -d "$b".mes-out > "$b".mes-d
|
||||
#readelf -a a.${cross_prefix}out > 1.r
|
||||
#readelf -a a.mes-out > 2.r
|
||||
#diff -y 1.a 2.a
|
||||
echo diff -y "$b".mes-gcc-stderr "$b".mes-stderr
|
||||
echo diff -y "$b".mes-gcc-d "$b".mes-d
|
||||
"$b".mes-out
|
|
@ -0,0 +1,856 @@
|
|||
/*************************************************************/
|
||||
/*
|
||||
* RISCV64 assembler for TCC
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef TARGET_DEFS_ONLY
|
||||
|
||||
#define CONFIG_TCC_ASM
|
||||
#define NB_ASM_REGS 32
|
||||
|
||||
ST_FUNC void g(int c);
|
||||
ST_FUNC void gen_le16(int c);
|
||||
ST_FUNC void gen_le32(int c);
|
||||
|
||||
/*************************************************************/
|
||||
#else
|
||||
/*************************************************************/
|
||||
#define USING_GLOBALS
|
||||
#include "tcc.h"
|
||||
|
||||
|
||||
/* XXX: make it faster ? */
|
||||
ST_FUNC void g(int c)
|
||||
{
|
||||
int ind1;
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
ind1 = ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(cur_text_section, ind1);
|
||||
cur_text_section->data[ind] = c;
|
||||
ind = ind1;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_le16 (int i)
|
||||
{
|
||||
g(i);
|
||||
g(i>>8);
|
||||
}
|
||||
|
||||
ST_FUNC void gen_le32 (int i)
|
||||
{
|
||||
int ind1;
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
ind1 = ind + 4;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(cur_text_section, ind1);
|
||||
cur_text_section->data[ind++] = i & 0xFF;
|
||||
cur_text_section->data[ind++] = (i >> 8) & 0xFF;
|
||||
cur_text_section->data[ind++] = (i >> 16) & 0xFF;
|
||||
cur_text_section->data[ind++] = (i >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
ST_FUNC void gen_expr32(ExprValue *pe)
|
||||
{
|
||||
gen_le32(pe->v);
|
||||
}
|
||||
|
||||
static void asm_emit_opcode(uint32_t opcode) {
|
||||
gen_le32(opcode);
|
||||
}
|
||||
|
||||
static void asm_nullary_opcode(TCCState *s1, int token)
|
||||
{
|
||||
switch (token) {
|
||||
// Sync instructions
|
||||
|
||||
case TOK_ASM_fence: // I
|
||||
asm_emit_opcode((0x3 << 2) | 3 | (0 << 12));
|
||||
return;
|
||||
case TOK_ASM_fence_i: // I
|
||||
asm_emit_opcode((0x3 << 2) | 3| (1 << 12));
|
||||
return;
|
||||
|
||||
// System calls
|
||||
|
||||
case TOK_ASM_ecall: // I (pseudo)
|
||||
asm_emit_opcode((0x1C << 2) | 3 | (0 << 12));
|
||||
return;
|
||||
case TOK_ASM_ebreak: // I (pseudo)
|
||||
asm_emit_opcode((0x1C << 2) | 3 | (0 << 12) | (1 << 20));
|
||||
return;
|
||||
|
||||
// Other
|
||||
|
||||
case TOK_ASM_wfi:
|
||||
asm_emit_opcode((0x1C << 2) | 3 | (0x105 << 20));
|
||||
return;
|
||||
|
||||
default:
|
||||
expect("nullary instruction");
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
OPT_REG,
|
||||
OPT_IM12S,
|
||||
OPT_IM32,
|
||||
OPT_IM20S,
|
||||
};
|
||||
#define OP_REG (1 << OPT_REG)
|
||||
#define OP_IM32 (1 << OPT_IM32)
|
||||
#define OP_IM12S (1 << OPT_IM12S)
|
||||
#define OP_IM20S (1 << OPT_IM20S)
|
||||
|
||||
typedef struct Operand {
|
||||
uint32_t type;
|
||||
union {
|
||||
uint8_t reg;
|
||||
uint16_t regset;
|
||||
ExprValue e;
|
||||
};
|
||||
} Operand;
|
||||
|
||||
/* Fixed operands for pseudoinstructions */
|
||||
const Operand zero_imm = {OP_IM12S, {0}};
|
||||
const Operand zero = {OP_REG, {0}};
|
||||
|
||||
|
||||
/* Parse a text containing operand and store the result in OP */
|
||||
static void parse_operand(TCCState *s1, Operand *op)
|
||||
{
|
||||
ExprValue e;
|
||||
int8_t reg;
|
||||
|
||||
op->type = 0;
|
||||
|
||||
if ((reg = asm_parse_regvar(tok)) != -1) {
|
||||
next(); // skip register name
|
||||
op->type = OP_REG;
|
||||
op->reg = (uint8_t) reg;
|
||||
return;
|
||||
} else if (tok == '$') {
|
||||
/* constant value */
|
||||
next(); // skip '#' or '$'
|
||||
}
|
||||
|
||||
asm_expr(s1, &e);
|
||||
op->e = e;
|
||||
if (!op->e.sym) {
|
||||
if ((int) op->e.v >= -2048 && (int) op->e.v < 2048)
|
||||
op->type = OP_IM12S;
|
||||
else if ((int) op->e.v >= -1<<19 && (int) op->e.v < 1<<19)
|
||||
op->type = OP_IM20S;
|
||||
else
|
||||
op->type = OP_IM32;
|
||||
return;
|
||||
} else {
|
||||
/*TODO: Deal with offsets and stuff like that for the moment it's ok to
|
||||
leave it like this as we are only taking the symbol case*/
|
||||
}
|
||||
}
|
||||
|
||||
#define ENCODE_RS1(register_index) ((register_index) << 15)
|
||||
#define ENCODE_RS2(register_index) ((register_index) << 20)
|
||||
#define ENCODE_RD(register_index) ((register_index) << 7)
|
||||
|
||||
// Note: Those all map to CSR--so they are pseudo-instructions.
|
||||
static void asm_unary_opcode(TCCState *s1, int token)
|
||||
{
|
||||
uint32_t opcode = (0x1C << 2) | 3 | (2 << 12);
|
||||
Operand op;
|
||||
parse_operand(s1, &op);
|
||||
if (op.type != OP_REG) {
|
||||
expect("register");
|
||||
return;
|
||||
}
|
||||
opcode |= ENCODE_RD(op.reg);
|
||||
|
||||
switch (token) {
|
||||
case TOK_ASM_rdcycle:
|
||||
asm_emit_opcode(opcode | (0xC00 << 20));
|
||||
return;
|
||||
case TOK_ASM_rdcycleh:
|
||||
asm_emit_opcode(opcode | (0xC80 << 20));
|
||||
return;
|
||||
case TOK_ASM_rdtime:
|
||||
asm_emit_opcode(opcode | (0xC01 << 20) | ENCODE_RD(op.reg));
|
||||
return;
|
||||
case TOK_ASM_rdtimeh:
|
||||
asm_emit_opcode(opcode | (0xC81 << 20) | ENCODE_RD(op.reg));
|
||||
return;
|
||||
case TOK_ASM_rdinstret:
|
||||
asm_emit_opcode(opcode | (0xC02 << 20) | ENCODE_RD(op.reg));
|
||||
return;
|
||||
case TOK_ASM_rdinstreth:
|
||||
asm_emit_opcode(opcode | (0xC82 << 20) | ENCODE_RD(op.reg));
|
||||
return;
|
||||
default:
|
||||
expect("unary instruction");
|
||||
}
|
||||
}
|
||||
|
||||
/* caller: Add funct3 into opcode */
|
||||
static void asm_emit_i(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
|
||||
{
|
||||
if (rd->type != OP_REG) {
|
||||
tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
if (rs1->type != OP_REG) {
|
||||
tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
if (rs2->type != OP_IM12S) {
|
||||
tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 4095", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
/* I-type instruction:
|
||||
31...20 imm[11:0]
|
||||
19...15 rs1
|
||||
14...12 funct3
|
||||
11...7 rd
|
||||
6...0 opcode */
|
||||
|
||||
gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | (rs2->e.v << 20));
|
||||
}
|
||||
|
||||
/* caller: Add funct3, funct7 into opcode */
|
||||
static void asm_emit_r(int token, uint32_t opcode, const Operand* rd, const Operand* rs1, const Operand* rs2)
|
||||
{
|
||||
if (rd->type != OP_REG) {
|
||||
tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
if (rs1->type != OP_REG) {
|
||||
tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
if (rs2->type != OP_REG) {
|
||||
tcc_error("'%s': Expected second source operand that is a register or immediate", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
/* R-type instruction:
|
||||
31...25 funct7
|
||||
24...20 rs2
|
||||
19...15 rs1
|
||||
14...12 funct3
|
||||
11...7 rd
|
||||
6...0 opcode */
|
||||
gen_le32(opcode | ENCODE_RD(rd->reg) | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg));
|
||||
}
|
||||
|
||||
|
||||
static void asm_emit_u(int token, uint32_t opcode, const Operand* rd, const Operand* rs2)
|
||||
{
|
||||
if (rd->type != OP_REG) {
|
||||
tcc_error("'%s': Expected destination operand that is a register", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
if (rs2->type != OP_IM12S && rs2->type != OP_IM32) {
|
||||
tcc_error("'%s': Expected second source operand that is an immediate value", get_tok_str(token, NULL));
|
||||
return;
|
||||
} else if (rs2->e.v >= 0x100000) {
|
||||
tcc_error("'%s': Expected second source operand that is an immediate value between 0 and 0xfffff", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
/* U-type instruction:
|
||||
31...12 imm[31:12]
|
||||
11...7 rd
|
||||
6...0 opcode */
|
||||
gen_le32(opcode | ENCODE_RD(rd->reg) | (rs2->e.v << 12));
|
||||
}
|
||||
|
||||
static void gen_lla(int token, Operand* op1, Operand* op2) {
|
||||
// 1. Generate the symbol first
|
||||
// 2. Generate a R_RISCV_PCREL_HI20 relocation pointing to the auipc for
|
||||
// the symbol
|
||||
// 3. Generate an auipc with 0x0
|
||||
// 4. Generate a R_RISCV_PCREL_LO12_I relocation pointing to the addi for
|
||||
// the symbol
|
||||
// 5. Generate an addi with 0x0
|
||||
// OPTIONAL. Add R_RISCV_RELAX
|
||||
//
|
||||
|
||||
Sym *sym, label = {0};
|
||||
sym = op2->e.sym;
|
||||
label.type.t = VT_VOID | VT_STATIC;
|
||||
put_extern_sym(&label, cur_text_section, ind, 0);
|
||||
greloca(cur_text_section, sym, ind, R_RISCV_PCREL_HI20, 0);
|
||||
asm_emit_u(token, (0x05 << 2) | 3, op1, &zero_imm); // auipc rd, 0x0
|
||||
greloca(cur_text_section, &label, ind, R_RISCV_PCREL_LO12_I, 0);
|
||||
asm_emit_i(token, (4 << 2) | 3, op1, op1, &zero_imm); // addi rd, rd, 0x0
|
||||
|
||||
// NOTE: We need to use an empty label (see `label` above) for this to
|
||||
// work, if we don't it fails saying the second relocation's value is not
|
||||
// the same as the addr of the previous one, and it's true.
|
||||
//
|
||||
// It returns this if we use sym in both relocations:
|
||||
// > PCREL_HI20: val=10230 addr=10260
|
||||
// > PCREL_LO12_I: val=10230 addr=10264
|
||||
// > tcc: error: unsupported hi/lo pcrel reloc scheme
|
||||
//
|
||||
// If we do it as in the code above it works properly.
|
||||
// I don't know why it should be like this, but it happens to work
|
||||
}
|
||||
static void gen_jal(int token, Operand* op1, Operand* op2) {
|
||||
Sym *sym;
|
||||
sym = op2->e.sym;
|
||||
greloca(cur_text_section, sym, ind, R_RISCV_JAL, 0);
|
||||
gen_le32( 0x6f | ENCODE_RD(op1->reg));
|
||||
}
|
||||
|
||||
static void asm_binary_opcode(TCCState* s1, int token)
|
||||
{
|
||||
Operand ops[2];
|
||||
|
||||
/* Parsing */
|
||||
parse_operand(s1, &ops[0]);
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[1]);
|
||||
|
||||
switch (token) {
|
||||
case TOK_ASM_la:
|
||||
/* TODO: implement la*/
|
||||
tcc_error("la is not implemented yet");
|
||||
case TOK_ASM_lla:
|
||||
if(!ops[1].e.sym){
|
||||
tcc_error("(%s): expected symbol as second argument", token);
|
||||
}
|
||||
gen_lla(token, &ops[0], &ops[1]);
|
||||
return;
|
||||
case TOK_ASM_mv:
|
||||
asm_emit_i(token, (4 << 2) | 3, &ops[0], &ops[1], &zero_imm);
|
||||
return;
|
||||
case TOK_ASM_neg:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (32 << 25), &ops[0], &zero, &ops[1]);
|
||||
return;
|
||||
case TOK_ASM_negw:
|
||||
asm_emit_r(token, (0xE << 2) | 3 | (0 << 12) | (32 << 25), &ops[0], &zero, &ops[1]);
|
||||
return;
|
||||
case TOK_ASM_li:
|
||||
/* NOTE: only works with small values! */
|
||||
asm_emit_i(token, (4 << 2) | 3, &ops[0], &zero, &ops[1]);
|
||||
return;
|
||||
case TOK_ASM_lui:
|
||||
asm_emit_u(token, (0xD << 2) | 3, &ops[0], &ops[1]);
|
||||
return;
|
||||
case TOK_ASM_auipc:
|
||||
asm_emit_u(token, (0x05 << 2) | 3, &ops[0], &ops[1]);
|
||||
return;
|
||||
default:
|
||||
expect("binary instruction");
|
||||
}
|
||||
}
|
||||
|
||||
static void asm_shift_opcode(TCCState *s1, int token)
|
||||
{
|
||||
Operand ops[3];
|
||||
parse_operand(s1, &ops[0]);
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[1]);
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[2]);
|
||||
|
||||
switch (token) {
|
||||
case TOK_ASM_sll:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_slli:
|
||||
asm_emit_i(token, (4 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_srl:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_srli:
|
||||
asm_emit_i(token, (0x4 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sra:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (5 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_srai:
|
||||
asm_emit_i(token, (0x4 << 2) | 3 | (5 << 12) | (16 << 26), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sllw:
|
||||
asm_emit_r(token, (0xE << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_slliw:
|
||||
asm_emit_i(token, (6 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_srlw:
|
||||
asm_emit_r(token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_srliw:
|
||||
asm_emit_i(token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sraw:
|
||||
asm_emit_r(token, (0xE << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sraiw:
|
||||
asm_emit_i(token, (0x6 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
default:
|
||||
expect("shift instruction");
|
||||
}
|
||||
}
|
||||
|
||||
static void asm_jump_opcode(TCCState* s1, int token)
|
||||
{
|
||||
Operand ops[3];
|
||||
int offset;
|
||||
parse_operand(s1, &ops[0]);
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[1]);
|
||||
if (token != TOK_ASM_jal){
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[2]);
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
case TOK_ASM_jalr:
|
||||
asm_emit_i(token, 0x67, &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_jal:
|
||||
if(ops[1].e.sym){
|
||||
// This handles `jal rd, symbol`
|
||||
gen_jal(token, &ops[0], &ops[1]);
|
||||
return;
|
||||
} else if(ops[1].type != OP_IM20S && ops[1].type != OP_IM12S) {
|
||||
tcc_error("jal jump too large");
|
||||
} else {
|
||||
// This is for immediates like `jal rd, -1201`
|
||||
// TODO: Make sure it works with positive and negative relative
|
||||
// jumps
|
||||
/* Weird encoding. It doesn't let us use `asm_emit_u` easily */
|
||||
offset = 0;
|
||||
offset = ((ops[1].e.v & 0x100000)>>20) <<19 |
|
||||
((ops[1].e.v & 0x0FF000)>>12) |
|
||||
((ops[1].e.v & 0x000800)>>11) <<8 |
|
||||
((ops[1].e.v & 0x0007FE)>> 1) <<9;
|
||||
gen_le32( 0x6f | ENCODE_RD(ops[0].reg) | offset<<12);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
expect("jump operation");
|
||||
}
|
||||
}
|
||||
static void asm_data_processing_opcode(TCCState* s1, int token)
|
||||
{
|
||||
Operand ops[3];
|
||||
parse_operand(s1, &ops[0]);
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[1]);
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[2]);
|
||||
|
||||
switch (token) {
|
||||
// Arithmetic (RD,RS1,(RS2|IMM)); R-format, I-format or U-format
|
||||
|
||||
case TOK_ASM_add:
|
||||
asm_emit_r(token, (0xC << 2) | 3, &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_addi:
|
||||
asm_emit_i(token, (4 << 2) | 3, &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sub:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (32 << 25), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_addw:
|
||||
asm_emit_r(token, (0xE << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_addiw: // 64 bit
|
||||
asm_emit_i(token, (0x6 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_subw:
|
||||
asm_emit_r(token, (0xE << 2) | 3 | (0 << 12) | (32 << 25), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
|
||||
// Logical (RD,RS1,(RS2|IMM)); R-format or I-format
|
||||
|
||||
case TOK_ASM_xor:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_xori:
|
||||
asm_emit_i(token, (0x4 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_or:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_ori:
|
||||
asm_emit_i(token, (0x4 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_and:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_andi:
|
||||
asm_emit_i(token, (0x4 << 2) | 3 | (7 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
|
||||
// Compare (RD,RS1,(RS2|IMM)); R-format or I-format
|
||||
|
||||
case TOK_ASM_slt:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_slti:
|
||||
asm_emit_i(token, (0x4 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sltu:
|
||||
asm_emit_r(token, (0xC << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sltiu:
|
||||
asm_emit_i(token, (0x4 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
default:
|
||||
expect("known data processing instruction");
|
||||
}
|
||||
}
|
||||
|
||||
/* caller: Add funct3 to opcode */
|
||||
static void asm_emit_s(int token, uint32_t opcode, const Operand* rs1, const Operand* rs2, const Operand* imm)
|
||||
{
|
||||
if (rs1->type != OP_REG) {
|
||||
tcc_error("'%s': Expected first source operand that is a register", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
if (rs2->type != OP_REG) {
|
||||
tcc_error("'%s': Expected second source operand that is a register", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
if (imm->type != OP_IM12S) {
|
||||
tcc_error("'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
{
|
||||
uint16_t v = imm->e.v;
|
||||
/* S-type instruction:
|
||||
31...25 imm[11:5]
|
||||
24...20 rs2
|
||||
19...15 rs1
|
||||
14...12 funct3
|
||||
11...7 imm[4:0]
|
||||
6...0 opcode
|
||||
opcode always fixed pos. */
|
||||
gen_le32(opcode | ENCODE_RS1(rs1->reg) | ENCODE_RS2(rs2->reg) | ((v & 0x1F) << 7) | ((v >> 5) << 25));
|
||||
}
|
||||
}
|
||||
|
||||
static void asm_data_transfer_opcode(TCCState* s1, int token)
|
||||
{
|
||||
Operand ops[3];
|
||||
parse_operand(s1, &ops[0]);
|
||||
if (ops[0].type != OP_REG) {
|
||||
expect("register");
|
||||
return;
|
||||
}
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[1]);
|
||||
if (ops[1].type != OP_REG) {
|
||||
expect("register");
|
||||
return;
|
||||
}
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[2]);
|
||||
|
||||
switch (token) {
|
||||
// Loads (RD,RS1,I); I-format
|
||||
|
||||
case TOK_ASM_lb:
|
||||
asm_emit_i(token, (0x0 << 2) | 3, &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_lh:
|
||||
asm_emit_i(token, (0x0 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_lw:
|
||||
asm_emit_i(token, (0x0 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_lbu:
|
||||
asm_emit_i(token, (0x0 << 2) | 3 | (4 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_lhu:
|
||||
asm_emit_i(token, (0x0 << 2) | 3 | (5 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
// 64 bit
|
||||
case TOK_ASM_ld:
|
||||
asm_emit_i(token, (0x0 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_lwu:
|
||||
asm_emit_i(token, (0x0 << 2) | 3 | (6 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
|
||||
// Stores (RS1,RS2,I); S-format
|
||||
|
||||
case TOK_ASM_sb:
|
||||
asm_emit_s(token, (0x8 << 2) | 3 | (0 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sh:
|
||||
asm_emit_s(token, (0x8 << 2) | 3 | (1 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sw:
|
||||
asm_emit_s(token, (0x8 << 2) | 3 | (2 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
case TOK_ASM_sd:
|
||||
asm_emit_s(token, (0x8 << 2) | 3 | (3 << 12), &ops[0], &ops[1], &ops[2]);
|
||||
return;
|
||||
|
||||
default:
|
||||
expect("known data transfer instruction");
|
||||
}
|
||||
}
|
||||
|
||||
static void asm_branch_opcode(TCCState* s1, int token)
|
||||
{
|
||||
// Branch (RS1,RS2,IMM); SB-format
|
||||
uint32_t opcode = (0x18 << 2) | 3;
|
||||
uint32_t offset = 0;
|
||||
Operand ops[3];
|
||||
parse_operand(s1, &ops[0]);
|
||||
if (ops[0].type != OP_REG) {
|
||||
expect("register");
|
||||
return;
|
||||
}
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[1]);
|
||||
if (ops[1].type != OP_REG) {
|
||||
expect("register");
|
||||
return;
|
||||
}
|
||||
if (tok == ',')
|
||||
next();
|
||||
else
|
||||
expect("','");
|
||||
parse_operand(s1, &ops[2]);
|
||||
|
||||
if (ops[2].type != OP_IM12S) {
|
||||
tcc_error("'%s': Expected third operand that is an immediate value between 0 and 0xfff", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
offset = ops[2].e.v;
|
||||
if (offset & 1) {
|
||||
tcc_error("'%s': Expected third operand that is an even immediate value", get_tok_str(token, NULL));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
case TOK_ASM_beq:
|
||||
opcode |= 0 << 12;
|
||||
break;
|
||||
case TOK_ASM_bne:
|
||||
opcode |= 1 << 12;
|
||||
break;
|
||||
case TOK_ASM_blt:
|
||||
opcode |= 4 << 12;
|
||||
break;
|
||||
case TOK_ASM_bge:
|
||||
opcode |= 5 << 12;
|
||||
break;
|
||||
case TOK_ASM_bltu:
|
||||
opcode |= 6 << 12;
|
||||
break;
|
||||
case TOK_ASM_bgeu:
|
||||
opcode |= 7 << 12;
|
||||
break;
|
||||
default:
|
||||
expect("known branch instruction");
|
||||
}
|
||||
asm_emit_opcode(opcode | ENCODE_RS1(ops[0].reg) | ENCODE_RS2(ops[1].reg) | (((offset >> 1) & 0xF) << 8) | (((offset >> 5) & 0x1f) << 25) | (((offset >> 11) & 1) << 7) | (((offset >> 12) & 1) << 31));
|
||||
}
|
||||
|
||||
ST_FUNC void asm_opcode(TCCState *s1, int token)
|
||||
{
|
||||
switch (token) {
|
||||
case TOK_ASM_fence:
|
||||
case TOK_ASM_fence_i:
|
||||
case TOK_ASM_ecall:
|
||||
case TOK_ASM_ebreak:
|
||||
case TOK_ASM_mrts:
|
||||
case TOK_ASM_mrth:
|
||||
case TOK_ASM_hrts:
|
||||
case TOK_ASM_wfi:
|
||||
asm_nullary_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_rdcycle:
|
||||
case TOK_ASM_rdcycleh:
|
||||
case TOK_ASM_rdtime:
|
||||
case TOK_ASM_rdtimeh:
|
||||
case TOK_ASM_rdinstret:
|
||||
case TOK_ASM_rdinstreth:
|
||||
asm_unary_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_li: /* pseudoinstruction */
|
||||
case TOK_ASM_mv: /* pseudoinstruction */
|
||||
case TOK_ASM_la: /* pseudoinstruction */
|
||||
case TOK_ASM_neg: /* pseudoinstruction */
|
||||
case TOK_ASM_negw: /* pseudoinstruction */
|
||||
case TOK_ASM_lla: /* pseudoinstruction */
|
||||
case TOK_ASM_lui:
|
||||
case TOK_ASM_auipc:
|
||||
asm_binary_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_sll:
|
||||
case TOK_ASM_slli:
|
||||
case TOK_ASM_srl:
|
||||
case TOK_ASM_srli:
|
||||
case TOK_ASM_sra:
|
||||
case TOK_ASM_srai:
|
||||
case TOK_ASM_sllw:
|
||||
case TOK_ASM_slld:
|
||||
case TOK_ASM_slliw:
|
||||
case TOK_ASM_sllid:
|
||||
case TOK_ASM_srlw:
|
||||
case TOK_ASM_srld:
|
||||
case TOK_ASM_srliw:
|
||||
case TOK_ASM_srlid:
|
||||
case TOK_ASM_sraw:
|
||||
case TOK_ASM_srad:
|
||||
case TOK_ASM_sraiw:
|
||||
case TOK_ASM_sraid:
|
||||
asm_shift_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_jalr:
|
||||
case TOK_ASM_jal:
|
||||
asm_jump_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_add:
|
||||
case TOK_ASM_addi:
|
||||
case TOK_ASM_sub:
|
||||
case TOK_ASM_addw:
|
||||
case TOK_ASM_addd:
|
||||
case TOK_ASM_addiw:
|
||||
case TOK_ASM_addid:
|
||||
case TOK_ASM_subw:
|
||||
case TOK_ASM_subd:
|
||||
case TOK_ASM_xor:
|
||||
case TOK_ASM_xori:
|
||||
case TOK_ASM_or:
|
||||
case TOK_ASM_ori:
|
||||
case TOK_ASM_and:
|
||||
case TOK_ASM_andi:
|
||||
case TOK_ASM_slt:
|
||||
case TOK_ASM_slti:
|
||||
case TOK_ASM_sltu:
|
||||
case TOK_ASM_sltiu:
|
||||
asm_data_processing_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_lb:
|
||||
case TOK_ASM_lh:
|
||||
case TOK_ASM_lw:
|
||||
case TOK_ASM_lbu:
|
||||
case TOK_ASM_lhu:
|
||||
case TOK_ASM_ld:
|
||||
case TOK_ASM_lwu:
|
||||
case TOK_ASM_sb:
|
||||
case TOK_ASM_sh:
|
||||
case TOK_ASM_sw:
|
||||
case TOK_ASM_sd:
|
||||
asm_data_transfer_opcode(s1, token);
|
||||
return;
|
||||
|
||||
case TOK_ASM_beq:
|
||||
case TOK_ASM_bne:
|
||||
case TOK_ASM_blt:
|
||||
case TOK_ASM_bge:
|
||||
case TOK_ASM_bltu:
|
||||
case TOK_ASM_bgeu:
|
||||
asm_branch_opcode(s1, token);
|
||||
return;
|
||||
|
||||
default:
|
||||
expect("known instruction");
|
||||
}
|
||||
}
|
||||
|
||||
ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
|
||||
{
|
||||
tcc_error("RISCV64 asm not implemented.");
|
||||
}
|
||||
|
||||
/* generate prolog and epilog code for asm statement */
|
||||
ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
||||
int nb_outputs, int is_output,
|
||||
uint8_t *clobber_regs,
|
||||
int out_reg)
|
||||
{
|
||||
}
|
||||
|
||||
ST_FUNC void asm_compute_constraints(ASMOperand *operands,
|
||||
int nb_operands, int nb_outputs,
|
||||
const uint8_t *clobber_regs,
|
||||
int *pout_reg)
|
||||
{
|
||||
}
|
||||
|
||||
ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
|
||||
{
|
||||
int reg;
|
||||
TokenSym *ts;
|
||||
|
||||
if (!strcmp(str, "memory") ||
|
||||
!strcmp(str, "cc") ||
|
||||
!strcmp(str, "flags"))
|
||||
return;
|
||||
ts = tok_alloc(str, strlen(str));
|
||||
reg = asm_parse_regvar(ts->tok);
|
||||
if (reg == -1) {
|
||||
tcc_error("invalid clobber register '%s'", str);
|
||||
}
|
||||
clobber_regs[reg] = 1;
|
||||
}
|
||||
|
||||
ST_FUNC int asm_parse_regvar (int t)
|
||||
{
|
||||
if (t >= TOK_ASM_x0 && t <= TOK_ASM_pc) { /* register name */
|
||||
if (t >= TOK_ASM_zero && t <= TOK_ASM_t6)
|
||||
return t - TOK_ASM_zero;
|
||||
switch (t) {
|
||||
case TOK_ASM_s0:
|
||||
return 8;
|
||||
case TOK_ASM_pc:
|
||||
tcc_error("PC register not implemented.");
|
||||
default:
|
||||
return t - TOK_ASM_x0;
|
||||
}
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
#endif /* ndef TARGET_DEFS_ONLY */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,361 @@
|
|||
#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 */
|
||||
|
||||
//#define DEBUG_RELOC
|
||||
#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) {
|
||||
|
||||
case R_RISCV_BRANCH:
|
||||
case R_RISCV_CALL:
|
||||
case R_RISCV_JAL:
|
||||
return 1;
|
||||
|
||||
case R_RISCV_GOT_HI20:
|
||||
case R_RISCV_PCREL_HI20:
|
||||
case R_RISCV_PCREL_LO12_I:
|
||||
case R_RISCV_PCREL_LO12_S:
|
||||
case R_RISCV_32_PCREL:
|
||||
case R_RISCV_SET6:
|
||||
case R_RISCV_SUB6:
|
||||
case R_RISCV_ADD16:
|
||||
case R_RISCV_ADD32:
|
||||
case R_RISCV_ADD64:
|
||||
case R_RISCV_SUB16:
|
||||
case R_RISCV_SUB32:
|
||||
case R_RISCV_SUB64:
|
||||
case R_RISCV_32:
|
||||
case R_RISCV_64:
|
||||
return 0;
|
||||
|
||||
case R_RISCV_CALL_PLT:
|
||||
return 1;
|
||||
}
|
||||
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) {
|
||||
case R_RISCV_ALIGN:
|
||||
case R_RISCV_RELAX:
|
||||
case R_RISCV_RVC_BRANCH:
|
||||
case R_RISCV_RVC_JUMP:
|
||||
case R_RISCV_JUMP_SLOT:
|
||||
case R_RISCV_SET6:
|
||||
case R_RISCV_SUB6:
|
||||
case R_RISCV_ADD16:
|
||||
case R_RISCV_SUB16:
|
||||
return NO_GOTPLT_ENTRY;
|
||||
|
||||
case R_RISCV_BRANCH:
|
||||
case R_RISCV_CALL:
|
||||
case R_RISCV_PCREL_HI20:
|
||||
case R_RISCV_PCREL_LO12_I:
|
||||
case R_RISCV_PCREL_LO12_S:
|
||||
case R_RISCV_32_PCREL:
|
||||
case R_RISCV_ADD32:
|
||||
case R_RISCV_ADD64:
|
||||
case R_RISCV_SUB32:
|
||||
case R_RISCV_SUB64:
|
||||
case R_RISCV_32:
|
||||
case R_RISCV_64:
|
||||
case R_RISCV_JAL:
|
||||
case R_RISCV_CALL_PLT:
|
||||
return AUTO_GOTPLT_ENTRY;
|
||||
|
||||
case R_RISCV_GOT_HI20:
|
||||
return ALWAYS_GOTPLT_ENTRY;
|
||||
}
|
||||
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 (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;
|
||||
}
|
||||
|
||||
static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
|
||||
|
||||
void relocate_init(Section *sr)
|
||||
{
|
||||
qrel = (ElfW_Rel *) sr->data;
|
||||
}
|
||||
|
||||
/* 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 - plt + 0x800) >> 12;
|
||||
if ((off + ((uint32_t)1 << 20)) >> 21)
|
||||
tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", (long)off, (long)got, (long)plt);
|
||||
write32le(p, 0x397 | (off << 12)); // auipc t2, %pcrel_hi(got)
|
||||
write32le(p + 4, 0x41c30333); // sub t1, t1, t3
|
||||
write32le(p + 8, 0x0003be03 // ld t3, %pcrel_lo(got)(t2)
|
||||
| (((got - plt) & 0xfff) << 20));
|
||||
write32le(p + 12, 0xfd430313); // addi t1, t1, -(32+12)
|
||||
write32le(p + 16, 0x00038293 // addi t0, t2, %pcrel_lo(got)
|
||||
| (((got - plt) & 0xfff) << 20));
|
||||
write32le(p + 20, 0x00135313); // srli t1, t1, log2(16/PTRSIZE)
|
||||
write32le(p + 24, 0x0082b283); // ld t0, PTRSIZE(t0)
|
||||
write32le(p + 28, 0x000e0067); // jr t3
|
||||
p += 32;
|
||||
while (p < p_end) {
|
||||
uint64_t pc = plt + (p - s1->plt->data);
|
||||
uint64_t addr = got + read64le(p);
|
||||
uint64_t off = (addr - pc + 0x800) >> 12;
|
||||
if ((off + ((uint32_t)1 << 20)) >> 21)
|
||||
tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", (long)off, (long)addr, (long)pc);
|
||||
write32le(p, 0xe17 | (off << 12)); // auipc t3, %pcrel_hi(func@got)
|
||||
write32le(p + 4, 0x000e3e03 // ld t3, %pcrel_lo(func@got)(t3)
|
||||
| (((addr - pc) & 0xfff) << 20));
|
||||
write32le(p + 8, 0x000e0367); // jalr t1, t3
|
||||
write32le(p + 12, 0x00000013); // nop
|
||||
p += 16;
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->plt->reloc) {
|
||||
ElfW_Rel *rel;
|
||||
p = s1->got->data;
|
||||
for (rel = (ElfW_Rel *) s1->plt->reloc->data; \
|
||||
rel < (ElfW_Rel *) (s1->plt->reloc->data + s1->plt->reloc->data_offset); \
|
||||
rel++) {
|
||||
write64le(p + rel->r_offset, s1->plt->sh_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
|
||||
addr_t addr, addr_t val)
|
||||
{
|
||||
uint64_t off64;
|
||||
uint32_t off32;
|
||||
int sym_index = ELFW(R_SYM)(rel->r_info), esym_index;
|
||||
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
|
||||
switch(type) {
|
||||
case R_RISCV_ALIGN:
|
||||
case R_RISCV_RELAX:
|
||||
return;
|
||||
|
||||
case R_RISCV_BRANCH:
|
||||
off64 = val - addr;
|
||||
if ((off64 + (1 << 12)) & ~(uint64_t)0x1ffe)
|
||||
tcc_error("R_RISCV_BRANCH relocation failed"
|
||||
" (val=%lx, addr=%lx)", (long)val, (long)addr);
|
||||
off32 = off64 >> 1;
|
||||
write32le(ptr, (read32le(ptr) & ~0xfe000f80)
|
||||
| ((off32 & 0x800) << 20)
|
||||
| ((off32 & 0x3f0) << 21)
|
||||
| ((off32 & 0x00f) << 8)
|
||||
| ((off32 & 0x400) >> 3));
|
||||
return;
|
||||
case R_RISCV_JAL:
|
||||
off64 = val - addr;
|
||||
if ((off64 + (1 << 21)) & ~(((uint64_t)1 << 22) - 2))
|
||||
tcc_error("R_RISCV_JAL relocation failed"
|
||||
" (val=%lx, addr=%lx)", (long)val, (long)addr);
|
||||
off32 = off64;
|
||||
write32le(ptr, (read32le(ptr) & 0xfff)
|
||||
| (((off32 >> 12) & 0xff) << 12)
|
||||
| (((off32 >> 11) & 1) << 20)
|
||||
| (((off32 >> 1) & 0x3ff) << 21)
|
||||
| (((off32 >> 20) & 1) << 31));
|
||||
return;
|
||||
case R_RISCV_CALL:
|
||||
case R_RISCV_CALL_PLT:
|
||||
write32le(ptr, (read32le(ptr) & 0xfff)
|
||||
| ((val - addr + 0x800) & ~0xfff));
|
||||
write32le(ptr + 4, (read32le(ptr + 4) & 0xfffff)
|
||||
| (((val - addr) & 0xfff) << 20));
|
||||
return;
|
||||
case R_RISCV_PCREL_HI20:
|
||||
#ifdef DEBUG_RELOC
|
||||
printf("PCREL_HI20: val=%lx addr=%lx\n", (long)val, (long)addr);
|
||||
#endif
|
||||
off64 = (int64_t)(val - addr + 0x800) >> 12;
|
||||
if ((off64 + ((uint64_t)1 << 20)) >> 21)
|
||||
tcc_error("R_RISCV_PCREL_HI20 relocation failed: off=%lx cond=%lx sym=%s",
|
||||
(long)off64, (long)((int64_t)(off64 + ((uint64_t)1 << 20)) >> 21),
|
||||
symtab_section->link->data + sym->st_name);
|
||||
write32le(ptr, (read32le(ptr) & 0xfff)
|
||||
| ((off64 & 0xfffff) << 12));
|
||||
last_hi.addr = addr;
|
||||
last_hi.val = val;
|
||||
return;
|
||||
case R_RISCV_GOT_HI20:
|
||||
val = s1->got->sh_addr + get_sym_attr(s1, sym_index, 0)->got_offset;
|
||||
off64 = (int64_t)(val - addr + 0x800) >> 12;
|
||||
if ((off64 + ((uint64_t)1 << 20)) >> 21)
|
||||
tcc_error("R_RISCV_GOT_HI20 relocation failed");
|
||||
last_hi.addr = addr;
|
||||
last_hi.val = val;
|
||||
write32le(ptr, (read32le(ptr) & 0xfff)
|
||||
| ((off64 & 0xfffff) << 12));
|
||||
return;
|
||||
case R_RISCV_PCREL_LO12_I:
|
||||
#ifdef DEBUG_RELOC
|
||||
printf("PCREL_LO12_I: val=%lx addr=%lx\n", (long)val, (long)addr);
|
||||
#endif
|
||||
if (val != last_hi.addr)
|
||||
tcc_error("unsupported hi/lo pcrel reloc scheme");
|
||||
val = last_hi.val;
|
||||
addr = last_hi.addr;
|
||||
write32le(ptr, (read32le(ptr) & 0xfffff)
|
||||
| (((val - addr) & 0xfff) << 20));
|
||||
return;
|
||||
case R_RISCV_PCREL_LO12_S:
|
||||
if (val != last_hi.addr)
|
||||
tcc_error("unsupported hi/lo pcrel reloc scheme");
|
||||
val = last_hi.val;
|
||||
addr = last_hi.addr;
|
||||
off32 = val - addr;
|
||||
write32le(ptr, (read32le(ptr) & ~0xfe000f80)
|
||||
| ((off32 & 0xfe0) << 20)
|
||||
| ((off32 & 0x01f) << 7));
|
||||
return;
|
||||
|
||||
case R_RISCV_RVC_BRANCH:
|
||||
off64 = (val - addr);
|
||||
if ((off64 + (1 << 8)) & ~(uint64_t)0x1fe)
|
||||
tcc_error("R_RISCV_RVC_BRANCH relocation failed"
|
||||
" (val=%lx, addr=%lx)", (long)val, (long)addr);
|
||||
off32 = off64;
|
||||
write16le(ptr, (read16le(ptr) & 0xe383)
|
||||
| (((off32 >> 5) & 1) << 2)
|
||||
| (((off32 >> 1) & 3) << 3)
|
||||
| (((off32 >> 6) & 3) << 5)
|
||||
| (((off32 >> 3) & 3) << 10)
|
||||
| (((off32 >> 8) & 1) << 12));
|
||||
return;
|
||||
case R_RISCV_RVC_JUMP:
|
||||
off64 = (val - addr);
|
||||
if ((off64 + (1 << 11)) & ~(uint64_t)0xffe)
|
||||
tcc_error("R_RISCV_RVC_BRANCH relocation failed"
|
||||
" (val=%lx, addr=%lx)", (long)val, (long)addr);
|
||||
off32 = off64;
|
||||
write16le(ptr, (read16le(ptr) & 0xe003)
|
||||
| (((off32 >> 5) & 1) << 2)
|
||||
| (((off32 >> 1) & 7) << 3)
|
||||
| (((off32 >> 7) & 1) << 6)
|
||||
| (((off32 >> 6) & 1) << 7)
|
||||
| (((off32 >> 10) & 1) << 8)
|
||||
| (((off32 >> 8) & 3) << 9)
|
||||
| (((off32 >> 4) & 1) << 11)
|
||||
| (((off32 >> 11) & 1) << 12));
|
||||
return;
|
||||
|
||||
case R_RISCV_32:
|
||||
if (s1->output_type == TCC_OUTPUT_DLL) {
|
||||
/* XXX: this logic may depend on TCC's codegen
|
||||
now TCC uses R_RISCV_RELATIVE even for a 64bit pointer */
|
||||
qrel->r_offset = rel->r_offset;
|
||||
qrel->r_info = ELFW(R_INFO)(0, R_RISCV_RELATIVE);
|
||||
/* Use sign extension! */
|
||||
qrel->r_addend = (int)read32le(ptr) + val;
|
||||
qrel++;
|
||||
}
|
||||
add32le(ptr, val);
|
||||
return;
|
||||
case R_RISCV_64:
|
||||
if (s1->output_type == TCC_OUTPUT_DLL) {
|
||||
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
|
||||
qrel->r_offset = rel->r_offset;
|
||||
if (esym_index) {
|
||||
qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_64);
|
||||
qrel->r_addend = rel->r_addend;
|
||||
qrel++;
|
||||
break;
|
||||
} else {
|
||||
qrel->r_info = ELFW(R_INFO)(0, R_RISCV_RELATIVE);
|
||||
qrel->r_addend = read64le(ptr) + val;
|
||||
qrel++;
|
||||
}
|
||||
}
|
||||
case R_RISCV_JUMP_SLOT:
|
||||
add64le(ptr, val);
|
||||
return;
|
||||
case R_RISCV_ADD64:
|
||||
write64le(ptr, read64le(ptr) + val);
|
||||
return;
|
||||
case R_RISCV_ADD32:
|
||||
write32le(ptr, read32le(ptr) + val);
|
||||
return;
|
||||
case R_RISCV_SUB64:
|
||||
write64le(ptr, read64le(ptr) - val);
|
||||
return;
|
||||
case R_RISCV_SUB32:
|
||||
write32le(ptr, read32le(ptr) - val);
|
||||
return;
|
||||
case R_RISCV_ADD16:
|
||||
write16le(ptr, read16le(ptr) + val);
|
||||
return;
|
||||
case R_RISCV_SUB16:
|
||||
write16le(ptr, read16le(ptr) - val);
|
||||
return;
|
||||
case R_RISCV_SET6:
|
||||
*ptr = (*ptr & ~0x3f) | (val & 0x3f);
|
||||
return;
|
||||
case R_RISCV_SUB6:
|
||||
*ptr = (*ptr & ~0x3f) | ((*ptr - val) & 0x3f);
|
||||
return;
|
||||
|
||||
case R_RISCV_32_PCREL:
|
||||
case R_RISCV_COPY:
|
||||
/* XXX */
|
||||
return;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
|
||||
type, (unsigned)addr, ptr, (unsigned)val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,204 @@
|
|||
/* ------------------------------------------------------------------ */
|
||||
/* WARNING: relative order of tokens is important. */
|
||||
|
||||
// See https://riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf
|
||||
|
||||
/* register */
|
||||
|
||||
DEF_ASM(x0)
|
||||
DEF_ASM(x1)
|
||||
DEF_ASM(x2)
|
||||
DEF_ASM(x3)
|
||||
DEF_ASM(x4)
|
||||
DEF_ASM(x5)
|
||||
DEF_ASM(x6)
|
||||
DEF_ASM(x7)
|
||||
DEF_ASM(x8)
|
||||
DEF_ASM(x9)
|
||||
DEF_ASM(x10)
|
||||
DEF_ASM(x11)
|
||||
DEF_ASM(x12)
|
||||
DEF_ASM(x13)
|
||||
DEF_ASM(x14)
|
||||
DEF_ASM(x15)
|
||||
DEF_ASM(x16)
|
||||
DEF_ASM(x17)
|
||||
DEF_ASM(x18)
|
||||
DEF_ASM(x19)
|
||||
DEF_ASM(x20)
|
||||
DEF_ASM(x21)
|
||||
DEF_ASM(x22)
|
||||
DEF_ASM(x23)
|
||||
DEF_ASM(x24)
|
||||
DEF_ASM(x25)
|
||||
DEF_ASM(x26)
|
||||
DEF_ASM(x27)
|
||||
DEF_ASM(x28)
|
||||
DEF_ASM(x29)
|
||||
DEF_ASM(x30)
|
||||
DEF_ASM(x31)
|
||||
|
||||
/* register macros */
|
||||
|
||||
DEF_ASM(zero)
|
||||
DEF_ASM(ra)
|
||||
DEF_ASM(sp)
|
||||
DEF_ASM(gp)
|
||||
DEF_ASM(tp)
|
||||
DEF_ASM(t0)
|
||||
DEF_ASM(t1)
|
||||
DEF_ASM(t2)
|
||||
DEF_ASM(fp)
|
||||
DEF_ASM(s1)
|
||||
DEF_ASM(a0)
|
||||
DEF_ASM(a1)
|
||||
DEF_ASM(a2)
|
||||
DEF_ASM(a3)
|
||||
DEF_ASM(a4)
|
||||
DEF_ASM(a5)
|
||||
DEF_ASM(a6)
|
||||
DEF_ASM(a7)
|
||||
DEF_ASM(s2)
|
||||
DEF_ASM(s3)
|
||||
DEF_ASM(s4)
|
||||
DEF_ASM(s5)
|
||||
DEF_ASM(s6)
|
||||
DEF_ASM(s7)
|
||||
DEF_ASM(s8)
|
||||
DEF_ASM(s9)
|
||||
DEF_ASM(s10)
|
||||
DEF_ASM(s11)
|
||||
DEF_ASM(t3)
|
||||
DEF_ASM(t4)
|
||||
DEF_ASM(t5)
|
||||
DEF_ASM(t6)
|
||||
|
||||
DEF_ASM(s0) // = x8
|
||||
|
||||
DEF_ASM(pc)
|
||||
|
||||
#define DEF_ASM_WITH_SUFFIX(x, y) \
|
||||
DEF(TOK_ASM_ ## x ## _ ## y, #x #y)
|
||||
|
||||
/* Pseudo*/
|
||||
DEF_ASM(li)
|
||||
DEF_ASM(la)
|
||||
DEF_ASM(lla)
|
||||
DEF_ASM(mv)
|
||||
DEF_ASM(neg)
|
||||
DEF_ASM(negw)
|
||||
|
||||
/* Jumps */
|
||||
DEF_ASM(jalr)
|
||||
DEF_ASM(jal)
|
||||
|
||||
/* Loads */
|
||||
|
||||
DEF_ASM(lb)
|
||||
DEF_ASM(lh)
|
||||
DEF_ASM(lw)
|
||||
DEF_ASM(lbu)
|
||||
DEF_ASM(lhu)
|
||||
DEF_ASM(ld)
|
||||
DEF_ASM(lq)
|
||||
DEF_ASM(lwu)
|
||||
DEF_ASM(ldu)
|
||||
|
||||
|
||||
/* Stores */
|
||||
|
||||
DEF_ASM(sb)
|
||||
DEF_ASM(sh)
|
||||
DEF_ASM(sw)
|
||||
DEF_ASM(sd)
|
||||
DEF_ASM(sq)
|
||||
|
||||
/* Shifts */
|
||||
|
||||
DEF_ASM(sll)
|
||||
DEF_ASM(slli)
|
||||
DEF_ASM(srl)
|
||||
DEF_ASM(srli)
|
||||
DEF_ASM(sra)
|
||||
DEF_ASM(srai)
|
||||
|
||||
DEF_ASM(sllw)
|
||||
DEF_ASM(slld)
|
||||
DEF_ASM(slliw)
|
||||
DEF_ASM(sllid)
|
||||
DEF_ASM(srlw)
|
||||
DEF_ASM(srld)
|
||||
DEF_ASM(srliw)
|
||||
DEF_ASM(srlid)
|
||||
DEF_ASM(sraw)
|
||||
DEF_ASM(srad)
|
||||
DEF_ASM(sraiw)
|
||||
DEF_ASM(sraid)
|
||||
|
||||
/* Arithmetic */
|
||||
|
||||
DEF_ASM(add)
|
||||
DEF_ASM(addi)
|
||||
DEF_ASM(sub)
|
||||
DEF_ASM(lui)
|
||||
DEF_ASM(auipc)
|
||||
|
||||
DEF_ASM(addw)
|
||||
DEF_ASM(addd)
|
||||
DEF_ASM(addiw)
|
||||
DEF_ASM(addid)
|
||||
DEF_ASM(subw)
|
||||
DEF_ASM(subd)
|
||||
|
||||
/* Logical */
|
||||
|
||||
DEF_ASM(xor)
|
||||
DEF_ASM(xori)
|
||||
DEF_ASM(or)
|
||||
DEF_ASM(ori)
|
||||
DEF_ASM(and)
|
||||
DEF_ASM(andi)
|
||||
|
||||
/* Compare */
|
||||
|
||||
DEF_ASM(slt)
|
||||
DEF_ASM(slti)
|
||||
DEF_ASM(sltu)
|
||||
DEF_ASM(sltiu)
|
||||
|
||||
/* Branch */
|
||||
|
||||
DEF_ASM(beq)
|
||||
DEF_ASM(bne)
|
||||
DEF_ASM(blt)
|
||||
DEF_ASM(bge)
|
||||
DEF_ASM(bltu)
|
||||
DEF_ASM(bgeu)
|
||||
|
||||
/* Sync */
|
||||
|
||||
DEF_ASM(fence)
|
||||
DEF_ASM_WITH_SUFFIX(fence, i)
|
||||
|
||||
/* System call */
|
||||
|
||||
DEF_ASM(ecall)
|
||||
DEF_ASM(ebreak)
|
||||
|
||||
|
||||
/* Counters */
|
||||
|
||||
DEF_ASM(rdcycle)
|
||||
DEF_ASM(rdcycleh)
|
||||
DEF_ASM(rdtime)
|
||||
DEF_ASM(rdtimeh)
|
||||
DEF_ASM(rdinstret)
|
||||
DEF_ASM(rdinstreth)
|
||||
|
||||
/* Privileged Instructions */
|
||||
|
||||
DEF_ASM(mrts)
|
||||
DEF_ASM(mrth)
|
||||
DEF_ASM(hrts)
|
||||
DEF_ASM(wfi)
|
||||
|
2
tcc.c
2
tcc.c
|
@ -153,6 +153,8 @@ static const char version[] =
|
|||
"ARM"
|
||||
#elif defined TCC_TARGET_ARM64
|
||||
"AArch64"
|
||||
#elif defined TCC_TARGET_RISCV64
|
||||
"riscv64"
|
||||
#endif
|
||||
#ifdef TCC_ARM_HARDFLOAT
|
||||
" Hard Float"
|
||||
|
|
62
tcc.h
62
tcc.h
|
@ -126,11 +126,12 @@
|
|||
/* #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)
|
||||
#define TCC_TARGET_I386
|
||||
#endif
|
||||
|
||||
|
@ -149,6 +150,8 @@
|
|||
# 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
|
||||
|
||||
|
@ -242,6 +245,8 @@
|
|||
# else
|
||||
# define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
|
||||
# endif
|
||||
# elif defined(TCC_TARGET_RISCV64)
|
||||
# define CONFIG_TCC_ELFINTERP "/lib/ld-linux-riscv64-lp64d.so.1"
|
||||
# elif !defined(TCC_ARM_EABI)
|
||||
# if defined(TCC_MUSL)
|
||||
# define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1"
|
||||
|
@ -320,6 +325,11 @@
|
|||
# include "c67-gen.c"
|
||||
# include "c67-link.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
# include "riscv64-gen.c"
|
||||
# include "riscv64-link.c"
|
||||
# include "riscv64-asm.c"
|
||||
#endif
|
||||
#undef TARGET_DEFS_ONLY
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -390,12 +400,21 @@ typedef union CValue {
|
|||
long double ld;
|
||||
double d;
|
||||
float f;
|
||||
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
|
||||
uint64_t i;
|
||||
#else
|
||||
uint32_t i;
|
||||
uint32_t i_padding;
|
||||
#endif
|
||||
struct {
|
||||
int size;
|
||||
const void *data;
|
||||
} str;
|
||||
#if BOOTSTRAP && __arm__
|
||||
int tab[4];
|
||||
#else
|
||||
int tab[LDOUBLE_SIZE/4];
|
||||
#endif
|
||||
} CValue;
|
||||
|
||||
/* value on stack */
|
||||
|
@ -407,9 +426,11 @@ typedef struct SValue {
|
|||
CValue c; /* constant, if VT_CONST */
|
||||
struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST), or if
|
||||
result of unary() for an identifier. */
|
||||
unsigned short cmp_r; // TODO
|
||||
} SValue;
|
||||
|
||||
struct Attribute {
|
||||
#if HAVE_BITFIELD
|
||||
unsigned
|
||||
func_call : 3, /* calling convention (0..5), see below */
|
||||
aligned : 5, /* alignment as log2+1 (0 == unspecified) */
|
||||
|
@ -423,6 +444,22 @@ struct Attribute {
|
|||
visibility : 2,
|
||||
unsigned_enum : 1,
|
||||
fill : 7; // 7 bits left to fit well in union below
|
||||
#else // !HAVE_BITFIELD
|
||||
struct {
|
||||
unsigned func_call;
|
||||
unsigned aligned;
|
||||
unsigned packed;
|
||||
unsigned func_export;
|
||||
unsigned func_import;
|
||||
unsigned func_args;
|
||||
unsigned func_body;
|
||||
unsigned mode;
|
||||
unsigned weak;
|
||||
unsigned visibility;
|
||||
unsigned unsigned_enum;
|
||||
unsigned fill;
|
||||
};
|
||||
#endif // !HAVE_BITFIELD
|
||||
};
|
||||
|
||||
/* GNUC attribute definition */
|
||||
|
@ -589,7 +626,12 @@ typedef struct CachedInclude {
|
|||
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
typedef struct ExprValue {
|
||||
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
|
||||
uint64_t v;
|
||||
#else
|
||||
uint32_t v;
|
||||
uint32_t v_padding;
|
||||
#endif
|
||||
Sym *sym;
|
||||
int pcrel;
|
||||
} ExprValue;
|
||||
|
@ -772,6 +814,11 @@ struct TCCState {
|
|||
/* tiny assembler state */
|
||||
Sym *asm_labels;
|
||||
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
struct pcrel_hi { addr_t addr, val; } last_hi;
|
||||
#define last_hi s1->last_hi
|
||||
#endif
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
/* PE info */
|
||||
int pe_subsystem;
|
||||
|
@ -1499,6 +1546,7 @@ static inline void write32le(unsigned char *p, uint32_t x) {
|
|||
static inline void add32le(unsigned char *p, int32_t x) {
|
||||
write32le(p, read32le(p) + x);
|
||||
}
|
||||
#if HAVE_LONG_LONG
|
||||
static inline uint64_t read64le(unsigned char *p) {
|
||||
return read32le(p) | (uint64_t)read32le(p + 4) << 32;
|
||||
}
|
||||
|
@ -1508,7 +1556,7 @@ static inline void write64le(unsigned char *p, uint64_t x) {
|
|||
static inline void add64le(unsigned char *p, int64_t x) {
|
||||
write64le(p, read64le(p) + x);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* ------------ i386-gen.c ------------ */
|
||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||
ST_FUNC void g(int c);
|
||||
|
@ -1548,6 +1596,16 @@ 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_opl(int op);
|
||||
//ST_FUNC void gfunc_return(CType *func_type);
|
||||
ST_FUNC void gen_va_start(void);
|
||||
ST_FUNC void arch_transfer_ret_regs(int);
|
||||
ST_FUNC void gen_cvt_sxtw(void);
|
||||
ST_FUNC void gen_increment_tcov (SValue *sv);
|
||||
#endif
|
||||
|
||||
/* ------------ c67-gen.c ------------ */
|
||||
#ifdef TCC_TARGET_C67
|
||||
#endif
|
||||
|
|
32
tccasm.c
32
tccasm.c
|
@ -18,7 +18,10 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
|
||||
ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
|
||||
|
@ -87,7 +90,11 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
|
|||
{
|
||||
Sym *sym;
|
||||
int op, label;
|
||||
#if HAVE_LONG_LONG
|
||||
uint64_t n;
|
||||
#else
|
||||
uint32_t n;
|
||||
#endif
|
||||
const char *p;
|
||||
|
||||
switch(tok) {
|
||||
|
@ -321,6 +328,7 @@ static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
|
|||
case TOK_NE:
|
||||
pe->v = pe->v != e2.v;
|
||||
break;
|
||||
#if HAVE_LONG_LONG
|
||||
case TOK_LT:
|
||||
pe->v = (int64_t)pe->v < (int64_t)e2.v;
|
||||
break;
|
||||
|
@ -333,11 +341,29 @@ static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
|
|||
case TOK_GT:
|
||||
pe->v = (int64_t)pe->v > (int64_t)e2.v;
|
||||
break;
|
||||
#else
|
||||
case TOK_LT:
|
||||
pe->v = (int32_t)pe->v < (int32_t)e2.v;
|
||||
break;
|
||||
case TOK_GE:
|
||||
pe->v = (int32_t)pe->v >= (int32_t)e2.v;
|
||||
break;
|
||||
case TOK_LE:
|
||||
pe->v = (int32_t)pe->v <= (int32_t)e2.v;
|
||||
break;
|
||||
case TOK_GT:
|
||||
pe->v = (int32_t)pe->v > (int32_t)e2.v;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#if HAVE_LONG_LONG
|
||||
/* GAS compare results are -1/0 not 1/0. */
|
||||
pe->v = -(int64_t)pe->v;
|
||||
#else
|
||||
pe->v = -(int32_t)pe->v;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,7 +545,11 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
#else
|
||||
next();
|
||||
for(;;) {
|
||||
#if HAVE_LONG_LONG
|
||||
uint64_t vl;
|
||||
#else
|
||||
uint32_t vl;
|
||||
#endif
|
||||
const char *p;
|
||||
|
||||
p = tokc.str.data;
|
||||
|
@ -534,7 +564,9 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
if (sec->sh_type != SHT_NOBITS) {
|
||||
/* XXX: endianness */
|
||||
gen_le32(vl);
|
||||
#if HAVE_LONG_LONG
|
||||
gen_le32(vl >> 32);
|
||||
#endif
|
||||
} else {
|
||||
ind += 8;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
|
||||
#define MAX_STR_TABLE 1000000
|
||||
|
|
95
tccelf.c
95
tccelf.c
|
@ -18,7 +18,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
/* Define this to get some debug output during relocation processing. */
|
||||
#undef DEBUG_RELOC
|
||||
|
@ -311,7 +313,12 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets)
|
|||
sym = (ElfW(Sym) *)s->data + 1;
|
||||
for(sym_index = 1; sym_index < nb_syms; sym_index++) {
|
||||
if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
|
||||
#if !BOOTSTRAP
|
||||
h = elf_hash(strtab + sym->st_name) % nb_buckets;
|
||||
#else
|
||||
h = elf_hash(strtab + sym->st_name);
|
||||
h = h % nb_buckets;
|
||||
#endif
|
||||
*ptr = hash[h];
|
||||
hash[h] = sym_index;
|
||||
} else {
|
||||
|
@ -353,7 +360,12 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
|
|||
if (ELFW(ST_BIND)(info) != STB_LOCAL) {
|
||||
/* add another hashing entry */
|
||||
nbuckets = base[0];
|
||||
#if !BOOTSTRAP
|
||||
h = elf_hash((unsigned char *) name) % nbuckets;
|
||||
#else
|
||||
h = elf_hash((unsigned char *) name);
|
||||
h = h % nbuckets;
|
||||
#endif
|
||||
*ptr = base[2 + h];
|
||||
base[2 + h] = sym_index;
|
||||
base[1]++;
|
||||
|
@ -383,7 +395,12 @@ ST_FUNC int find_elf_sym(Section *s, const char *name)
|
|||
if (!hs)
|
||||
return 0;
|
||||
nbuckets = ((int *)hs->data)[0];
|
||||
#if !BOOTSTRAP
|
||||
h = elf_hash((unsigned char *) name) % nbuckets;
|
||||
#else
|
||||
h = elf_hash((unsigned char *) name);
|
||||
h = h % nbuckets;
|
||||
#endif
|
||||
sym_index = ((int *)hs->data)[2 + h];
|
||||
while (sym_index != 0) {
|
||||
sym = &((ElfW(Sym) *)s->data)[sym_index];
|
||||
|
@ -411,6 +428,14 @@ ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
|
|||
return sym->st_value;
|
||||
}
|
||||
|
||||
#if __MESC_MES__ || !__MESC__
|
||||
#if !defined (__intptr_t_defined) && !defined (__MES_INTPTR_T)
|
||||
typedef unsigned long uintptr_t;
|
||||
#endif
|
||||
#else // guile
|
||||
#undef uintptr_t
|
||||
#endif
|
||||
|
||||
/* return elf symbol value */
|
||||
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
|
||||
{
|
||||
|
@ -425,6 +450,16 @@ ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
|
|||
}
|
||||
#endif
|
||||
|
||||
ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
|
||||
{
|
||||
int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
|
||||
if (sec && offs == -1)
|
||||
offs = sec->data_offset;
|
||||
return set_elf_sym(symtab_section, offs, 0,
|
||||
ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
|
||||
}
|
||||
|
||||
|
||||
/* add an elf symbol : check if it is already defined and patch
|
||||
it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
|
||||
ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||
|
@ -554,7 +589,7 @@ ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
|
|||
ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
|
||||
{
|
||||
Section *sr = s->reloc;
|
||||
ElfW_Rel *r, *dest;
|
||||
ElfW_Rel *r, *dest, tmp;
|
||||
ssize_t a;
|
||||
ElfW(Addr) addr;
|
||||
|
||||
|
@ -566,10 +601,14 @@ ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
|
|||
a simple insertion sort. */
|
||||
for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
|
||||
ssize_t i = a - sizeof(*r);
|
||||
addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
|
||||
///addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
|
||||
ElfW_Rel* ea = (ElfW_Rel*)(sr->data + a);
|
||||
ElfW_Rel* ei = (ElfW_Rel*)(sr->data + i);
|
||||
addr = ea->r_offset;
|
||||
for (; i >= (ssize_t)oldrelocoffset &&
|
||||
((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
|
||||
ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
|
||||
ei->r_offset > addr; i -= sizeof(*r)) {
|
||||
ei = (ElfW_Rel*)(sr->data + i);
|
||||
tmp = *(ElfW_Rel*)(sr->data + a);
|
||||
*(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
|
||||
*(ElfW_Rel*)(sr->data + i) = tmp;
|
||||
}
|
||||
|
@ -817,20 +856,36 @@ static void relocate_rel(TCCState *s1, Section *sr)
|
|||
their space */
|
||||
static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
||||
{
|
||||
int count = 0;
|
||||
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
|
||||
defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
|
||||
defined(TCC_TARGET_RISCV64)
|
||||
ElfW_Rel *rel;
|
||||
int sym_index, type, count;
|
||||
|
||||
count = 0;
|
||||
for_each_elem(sr, 0, rel, ElfW_Rel) {
|
||||
sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
type = ELFW(R_TYPE)(rel->r_info);
|
||||
int sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
int type = ELFW(R_TYPE)(rel->r_info);
|
||||
switch(type) {
|
||||
#if defined(TCC_TARGET_I386)
|
||||
case R_386_32:
|
||||
if (!get_sym_attr(s1, sym_index, 0)->dyn_index
|
||||
&& ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
|
||||
/* don't fixup unresolved (weak) symbols */
|
||||
rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
|
||||
break;
|
||||
}
|
||||
#elif defined(TCC_TARGET_X86_64)
|
||||
case R_X86_64_32:
|
||||
case R_X86_64_32S:
|
||||
case R_X86_64_64:
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_TARGET1:
|
||||
#elif defined(TCC_TARGET_ARM64)
|
||||
case R_AARCH64_ABS32:
|
||||
case R_AARCH64_ABS64:
|
||||
#elif defined(TCC_TARGET_RISCV64)
|
||||
case R_RISCV_32:
|
||||
case R_RISCV_64:
|
||||
#endif
|
||||
count++;
|
||||
break;
|
||||
|
@ -851,6 +906,7 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
|||
sr->sh_flags |= SHF_ALLOC;
|
||||
sr->sh_size = count * sizeof(ElfW_Rel);
|
||||
}
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -1147,6 +1203,9 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
|
|||
}
|
||||
#endif
|
||||
tcc_add_support(s1, TCC_LIBTCC1);
|
||||
#if CONFIG_TCC_LIBTCC1_MES
|
||||
tcc_add_support(s1, TCC_LIBTCC1_MES);
|
||||
#endif
|
||||
/* add crt end if not memory output */
|
||||
if (s1->output_type != TCC_OUTPUT_MEMORY)
|
||||
tcc_add_crt(s1, "crtn.o");
|
||||
|
@ -1174,6 +1233,10 @@ ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
|
|||
bss_section->data_offset, 0,
|
||||
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
||||
bss_section->sh_num, "_end");
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
/* XXX should be .sdata+0x800, not .data+0x800 */
|
||||
set_global_sym(s1, "__global_pointer$", data_section, 0x800);
|
||||
#endif
|
||||
#ifndef TCC_TARGET_PE
|
||||
/* horrible new standard ldscript defines */
|
||||
add_init_array_defines(s1, ".preinit_array");
|
||||
|
@ -1781,7 +1844,7 @@ static int final_sections_reloc(TCCState *s1)
|
|||
/* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
|
||||
checking is removed */
|
||||
#else
|
||||
if (s->reloc && s != s1->got)
|
||||
if (s->reloc)
|
||||
/* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
|
||||
#endif
|
||||
relocate_section(s1, s);
|
||||
|
@ -1835,7 +1898,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
|||
ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM
|
||||
#ifdef TCC_ARM_EABI
|
||||
#if defined (TCC_ARM_EABI) || BOOTSTRAP
|
||||
ehdr.e_ident[EI_OSABI] = 0;
|
||||
ehdr.e_flags = EF_ARM_EABI_VER4;
|
||||
if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
|
||||
|
@ -1847,6 +1910,8 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
|||
#else
|
||||
ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
|
||||
#endif
|
||||
#elif defined TCC_TARGET_RISCV64
|
||||
ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
|
||||
#endif
|
||||
switch(file_type) {
|
||||
default:
|
||||
|
@ -2161,13 +2226,14 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
|||
}
|
||||
}
|
||||
|
||||
/* if building executable or DLL, then relocate each section
|
||||
except the GOT which is already relocated */
|
||||
/* if building executable or DLL, then relocate each section */
|
||||
if (file_type != TCC_OUTPUT_OBJ) {
|
||||
ret = final_sections_reloc(s1);
|
||||
if (ret)
|
||||
goto the_end;
|
||||
#if !BOOTSTRAP
|
||||
tidy_section_headers(s1, sec_order);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Perform relocation to GOT or PLT entries */
|
||||
|
@ -2482,6 +2548,9 @@ ST_FUNC int tcc_load_object_file(TCCState *s1,
|
|||
if (!sym_index && !sm->link_once
|
||||
#ifdef TCC_TARGET_ARM
|
||||
&& type != R_ARM_V4BX
|
||||
#elif defined TCC_TARGET_RISCV64
|
||||
&& type != R_RISCV_ALIGN
|
||||
&& type != R_RISCV_RELAX
|
||||
#endif
|
||||
) {
|
||||
invalid_reloc:
|
||||
|
|
234
tccgen.c
234
tccgen.c
|
@ -18,7 +18,16 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#if BOOTSTRAP && __arm__
|
||||
void
|
||||
tccgen_ok ()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************/
|
||||
/* global variables */
|
||||
|
@ -62,7 +71,11 @@ ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
|
|||
|
||||
ST_DATA struct switch_t {
|
||||
struct case_t {
|
||||
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
|
||||
int64_t v1, v2;
|
||||
#else
|
||||
int32_t v1, v1_padding, v2, v2_padding;
|
||||
#endif
|
||||
int sym;
|
||||
} **p; int n; /* list of case ranges */
|
||||
int def_sym; /* default symbol */
|
||||
|
@ -86,8 +99,12 @@ static void vla_runtime_type_size(CType *type, int *a);
|
|||
static void vla_sp_restore(void);
|
||||
static void vla_sp_restore_root(void);
|
||||
static int is_compatible_parameter_types(CType *type1, CType *type2);
|
||||
#if HAVE_LONG_LONG
|
||||
static inline int64_t expr_const64(void);
|
||||
ST_FUNC void vpush64(int ty, unsigned long long v);
|
||||
#else
|
||||
static inline int32_t expr_const32(void);
|
||||
#endif
|
||||
ST_FUNC void vpush(CType *type);
|
||||
ST_FUNC int gvtst(int inv, int t);
|
||||
ST_FUNC int is_btype_size(int bt);
|
||||
|
@ -270,13 +287,16 @@ static void update_storage(Sym *sym)
|
|||
t = sym->type.t;
|
||||
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
|
||||
|
||||
#if !__MESC__ // Nyacc 0.80.40 cpp-bug
|
||||
if (t & VT_VIS_MASK)
|
||||
esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
|
||||
| ((t & VT_VIS_MASK) >> VT_VIS_SHIFT);
|
||||
|
||||
if (t & VT_WEAK)
|
||||
esym->st_info = ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(esym->st_info));
|
||||
|
||||
#else //__MESC__
|
||||
// #warning work around Nyacc 0.80.42 bug.
|
||||
#endif // __MESC__
|
||||
#ifdef TCC_TARGET_PE
|
||||
if (t & VT_EXPORT)
|
||||
esym->st_other |= ST_PE_EXPORT;
|
||||
|
@ -1113,6 +1133,11 @@ ST_FUNC int gv(int rc)
|
|||
if (vtop->r & VT_MUSTBOUND)
|
||||
gbound();
|
||||
#endif
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
/* XXX mega hack */
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE && rc == RC_FLOAT)
|
||||
rc = RC_INT;
|
||||
#endif
|
||||
|
||||
r = vtop->r & VT_VALMASK;
|
||||
rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
|
||||
|
@ -1131,7 +1156,10 @@ ST_FUNC int gv(int rc)
|
|||
if (r >= VT_CONST
|
||||
|| (vtop->r & VT_LVAL)
|
||||
|| !(reg_classes[r] & rc)
|
||||
#if PTR_SIZE == 8
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
|| ((vtop->type.t & VT_BTYPE) == VT_QLONG && (vtop->r2 >= NB_REGS || !(reg_classes[vtop->r2] & rc2)))
|
||||
|| ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE && (vtop->r2 >= NB_REGS || !(reg_classes[vtop->r2] & rc2)))
|
||||
#elif PTR_SIZE == 8
|
||||
|| ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
|
||||
|| ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
|
||||
#else
|
||||
|
@ -1140,7 +1168,10 @@ ST_FUNC int gv(int rc)
|
|||
)
|
||||
{
|
||||
r = get_reg(rc);
|
||||
#if PTR_SIZE == 8
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)) {
|
||||
int addr_type = VT_LLONG, load_size = 8, load_type = VT_LLONG;
|
||||
#elif PTR_SIZE == 8
|
||||
if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
|
||||
int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
|
||||
#else
|
||||
|
@ -1272,6 +1303,9 @@ static int rc_fret(int t)
|
|||
if (t == VT_LDOUBLE) {
|
||||
return RC_ST0;
|
||||
}
|
||||
#elif defined TCC_TARGET_RISCV64
|
||||
if (t == VT_LDOUBLE)
|
||||
return RC_IRET;
|
||||
#endif
|
||||
return RC_FRET;
|
||||
}
|
||||
|
@ -1284,6 +1318,9 @@ static int reg_fret(int t)
|
|||
if (t == VT_LDOUBLE) {
|
||||
return TREG_ST0;
|
||||
}
|
||||
#elif defined TCC_TARGET_RISCV64
|
||||
if (t == VT_LDOUBLE)
|
||||
return REG_IRET;
|
||||
#endif
|
||||
return REG_FRET;
|
||||
}
|
||||
|
@ -1297,7 +1334,9 @@ static void lexpand(void)
|
|||
v = vtop->r & (VT_VALMASK | VT_LVAL);
|
||||
if (v == VT_CONST) {
|
||||
vdup();
|
||||
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
|
||||
vtop[0].c.i >>= 32;
|
||||
#endif
|
||||
} else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
|
||||
vdup();
|
||||
vtop[0].c.i += 4;
|
||||
|
@ -1324,7 +1363,9 @@ ST_FUNC void lexpand_nr(void)
|
|||
v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
|
||||
if (v == VT_CONST) {
|
||||
vtop[-1].c.i = vtop->c.i;
|
||||
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
|
||||
vtop->c.i = vtop->c.i >> 32;
|
||||
#endif
|
||||
vtop->r = VT_CONST;
|
||||
} else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
|
||||
vtop->c.i += 4;
|
||||
|
@ -1385,6 +1426,9 @@ static void gv_dup(void)
|
|||
if ((t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
rc = RC_ST0;
|
||||
}
|
||||
#elif defined TCC_TARGET_RISCV64
|
||||
if ((t & VT_BTYPE) == VT_LDOUBLE)
|
||||
rc = RC_INT;
|
||||
#endif
|
||||
sv.type.t = t;
|
||||
}
|
||||
|
@ -1649,16 +1693,38 @@ static void gen_opl(int op)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
|
||||
static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
|
||||
{
|
||||
#if HAVE_LONG_LONG
|
||||
uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
|
||||
return (a ^ b) >> 63 ? -x : x;
|
||||
#else
|
||||
uint32_t x = (a >> 31 ? -a : a) / (b >> 31 ? -b : b);
|
||||
return (a ^ b) >> 31 ? -x : x;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int gen_opic_lt(uint64_t a, uint64_t b)
|
||||
{
|
||||
#if HAVE_LONG_LONG
|
||||
return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
|
||||
#else
|
||||
return (a ^ (uint32_t)1 << 31) < (b ^ (uint32_t)1 << 31);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static uint32_t gen_opic_sdiv(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t x = (a >> 31 ? -a : a) / (b >> 31 ? -b : b);
|
||||
return (a ^ b) >> 31 ? -x : x;
|
||||
}
|
||||
|
||||
static int gen_opic_lt(uint32_t a, uint32_t b)
|
||||
{
|
||||
return (a ^ (uint32_t)1 << 31) < (b ^ (uint32_t)1 << 31);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* handle integer constant optimizations and various machine
|
||||
independent opt */
|
||||
|
@ -1670,10 +1736,15 @@ static void gen_opic(int op)
|
|||
int t2 = v2->type.t & VT_BTYPE;
|
||||
int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
||||
int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
||||
#if HAVE_LONG_LONG
|
||||
uint64_t l1 = c1 ? v1->c.i : 0;
|
||||
uint64_t l2 = c2 ? v2->c.i : 0;
|
||||
int shm = (t1 == VT_LLONG) ? 63 : 31;
|
||||
|
||||
#else
|
||||
uint32_t l1 = c1 ? v1->c.i : 0;
|
||||
uint32_t l2 = c2 ? v2->c.i : 0;
|
||||
int shm = 31;
|
||||
#endif
|
||||
if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
|
||||
l1 = ((uint32_t)l1 |
|
||||
(v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
|
||||
|
@ -1711,7 +1782,11 @@ static void gen_opic(int op)
|
|||
case TOK_SHL: l1 <<= (l2 & shm); break;
|
||||
case TOK_SHR: l1 >>= (l2 & shm); break;
|
||||
case TOK_SAR:
|
||||
#if HAVE_LONG_LONG
|
||||
l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
|
||||
#else
|
||||
l1 = (l1 >> 31) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
|
||||
#endif
|
||||
break;
|
||||
/* tests */
|
||||
case TOK_ULT: l1 = l1 < l2; break;
|
||||
|
@ -1845,11 +1920,13 @@ static void gen_opif(int op)
|
|||
case '-': f1 -= f2; break;
|
||||
case '*': f1 *= f2; break;
|
||||
case '/':
|
||||
#if HAVE_FLOAT
|
||||
if (f2 == 0.0) {
|
||||
if (const_wanted)
|
||||
tcc_error("division by zero in constant");
|
||||
goto general_case;
|
||||
}
|
||||
#endif
|
||||
f1 /= f2;
|
||||
break;
|
||||
/* XXX: also handles tests ? */
|
||||
|
@ -2267,6 +2344,7 @@ static void gen_cast(CType *type)
|
|||
if (c) {
|
||||
/* constant case: we can do it now */
|
||||
/* XXX: in ISOC, cannot do it if error in convert */
|
||||
#if HAVE_FLOAT
|
||||
if (sbt == VT_FLOAT)
|
||||
vtop->c.ld = vtop->c.f;
|
||||
else if (sbt == VT_DOUBLE)
|
||||
|
@ -2289,14 +2367,20 @@ static void gen_cast(CType *type)
|
|||
vtop->c.f = (float)vtop->c.ld;
|
||||
else if (dbt == VT_DOUBLE)
|
||||
vtop->c.d = (double)vtop->c.ld;
|
||||
} else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
|
||||
}
|
||||
else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
|
||||
vtop->c.i = vtop->c.ld;
|
||||
} else if (sf && dbt == VT_BOOL) {
|
||||
vtop->c.i = (vtop->c.ld != 0);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#if HAVE_FLOAT
|
||||
if(sf)
|
||||
vtop->c.i = vtop->c.ld;
|
||||
else if (sbt == (VT_LLONG|VT_UNSIGNED))
|
||||
else
|
||||
#endif
|
||||
if (sbt == (VT_LLONG|VT_UNSIGNED))
|
||||
;
|
||||
else if (sbt & VT_UNSIGNED)
|
||||
vtop->c.i = (uint32_t)vtop->c.i;
|
||||
|
@ -2388,7 +2472,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);
|
||||
|
@ -2906,7 +2990,11 @@ ST_FUNC void vstore(void)
|
|||
else
|
||||
#endif
|
||||
/* Use memmove, rather than memcpy, as dest and src may be same: */
|
||||
#if BOOTSTRAP && __arm__
|
||||
vpush_global_sym(&func_old_type, TOK___memmove);
|
||||
#else
|
||||
vpush_global_sym(&func_old_type, TOK_memmove);
|
||||
#endif
|
||||
|
||||
vswap();
|
||||
/* source */
|
||||
|
@ -2981,6 +3069,9 @@ ST_FUNC void vstore(void)
|
|||
} else if ((ft & VT_BTYPE) == VT_QFLOAT) {
|
||||
rc = RC_FRET;
|
||||
}
|
||||
#elif defined TCC_TARGET_RISCV64
|
||||
if (dbt == VT_LDOUBLE)
|
||||
rc = RC_INT;
|
||||
#endif
|
||||
}
|
||||
r = gv(rc); /* generate value */
|
||||
|
@ -2999,7 +3090,10 @@ ST_FUNC void vstore(void)
|
|||
vtop[-1].r = t | VT_LVAL;
|
||||
}
|
||||
/* two word case handling : store second register at word + 4 (or +8 for x86-64) */
|
||||
#if PTR_SIZE == 8
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
if (dbt == VT_QLONG || dbt == VT_LDOUBLE) {
|
||||
int addr_type = VT_LLONG, load_size = 8, load_type = VT_LLONG;
|
||||
#elif PTR_SIZE == 8
|
||||
if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
|
||||
int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
|
||||
#else
|
||||
|
@ -3760,7 +3854,7 @@ static int parse_btype(CType *type, AttributeDef *ad)
|
|||
goto basic_type1;
|
||||
}
|
||||
break;
|
||||
#ifdef TCC_TARGET_ARM64
|
||||
#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
|
||||
case TOK_UINT128:
|
||||
/* GCC's __uint128_t appears in some Linux header files. Make it a
|
||||
synonym for long double to get the size and alignment right. */
|
||||
|
@ -4524,10 +4618,18 @@ ST_FUNC void unary(void)
|
|||
break;
|
||||
case TOK_builtin_choose_expr:
|
||||
{
|
||||
#if HAVE_LONG_LONG_STUB || HAVE_LONG_LONG
|
||||
int64_t c;
|
||||
#else
|
||||
int32_t c;
|
||||
#endif
|
||||
next();
|
||||
skip('(');
|
||||
#if HAVE_LONG_LONG
|
||||
c = expr_const64();
|
||||
#else
|
||||
c = expr_const32();
|
||||
#endif
|
||||
skip(',');
|
||||
if (!c) {
|
||||
nocode_wanted++;
|
||||
|
@ -4588,6 +4690,18 @@ ST_FUNC void unary(void)
|
|||
}
|
||||
}
|
||||
break;
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
case TOK_builtin_va_start:
|
||||
parse_builtin_params(0, "ee");
|
||||
r = vtop->r & VT_VALMASK;
|
||||
if (r == VT_LLOCAL)
|
||||
r = VT_LOCAL;
|
||||
if (r != VT_LOCAL)
|
||||
tcc_error("__builtin_va_start expects a local variable");
|
||||
gen_va_start();
|
||||
vstore();
|
||||
break;
|
||||
#endif
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
#ifdef TCC_TARGET_PE
|
||||
case TOK_builtin_va_start:
|
||||
|
@ -4655,12 +4769,14 @@ ST_FUNC void unary(void)
|
|||
/* In IEEE negate(x) isn't subtract(0,x), but rather
|
||||
subtract(-0, x). */
|
||||
vpush(&vtop->type);
|
||||
#if HAVE_FLOAT
|
||||
if (t == VT_FLOAT)
|
||||
vtop->c.f = -1.0 * 0.0;
|
||||
else if (t == VT_DOUBLE)
|
||||
vtop->c.d = -1.0 * 0.0;
|
||||
else
|
||||
vtop->c.ld = -1.0 * 0.0;
|
||||
#endif
|
||||
} else
|
||||
vpushi(0);
|
||||
vswap();
|
||||
|
@ -4691,15 +4807,31 @@ ST_FUNC void unary(void)
|
|||
|
||||
// special qnan , snan and infinity values
|
||||
case TOK___NAN__:
|
||||
#if HAVE_LONG_LONG
|
||||
vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
|
||||
#else
|
||||
vpush64(VT_DOUBLE, 0x7ff80000);
|
||||
vtop->c.i = vtop->c.i << 32;
|
||||
#endif
|
||||
next();
|
||||
break;
|
||||
case TOK___SNAN__:
|
||||
#if HAVE_LONG_LONG
|
||||
vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
|
||||
#else
|
||||
vpush64(VT_DOUBLE, 0x7ff00000);
|
||||
vtop->c.i = vtop->c.i << 32;
|
||||
vtop->c.i = vtop->c.i | 1;
|
||||
#endif
|
||||
next();
|
||||
break;
|
||||
case TOK___INF__:
|
||||
#if HAVE_LONG_LONG
|
||||
vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
|
||||
#else
|
||||
vpush64(VT_DOUBLE, 0x7ff00000);
|
||||
vtop->c.i = vtop->c.i << 32;
|
||||
#endif
|
||||
next();
|
||||
break;
|
||||
|
||||
|
@ -5141,6 +5273,9 @@ static void expr_cond(void)
|
|||
if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
rc = RC_ST0;
|
||||
}
|
||||
#elif defined TCC_TARGET_RISCV64
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
|
||||
rc = RC_INT;
|
||||
#endif
|
||||
} else
|
||||
rc = RC_INT;
|
||||
|
@ -5252,6 +5387,9 @@ static void expr_cond(void)
|
|||
if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
rc = RC_ST0;
|
||||
}
|
||||
#elif defined TCC_TARGET_RISCV64
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
|
||||
rc = RC_INT;
|
||||
#endif
|
||||
} else if ((type.t & VT_BTYPE) == VT_LLONG) {
|
||||
/* for long longs, we use fixed registers to avoid having
|
||||
|
@ -5332,6 +5470,7 @@ static void expr_const1(void)
|
|||
const_wanted--;
|
||||
}
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* parse an integer constant and return its value. */
|
||||
static inline int64_t expr_const64(void)
|
||||
{
|
||||
|
@ -5343,13 +5482,30 @@ static inline int64_t expr_const64(void)
|
|||
vpop();
|
||||
return c;
|
||||
}
|
||||
#else
|
||||
/* parse an integer constant and return its value. */
|
||||
static inline int32_t expr_const32(void)
|
||||
{
|
||||
int32_t c;
|
||||
expr_const1();
|
||||
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
|
||||
expect("constant expression");
|
||||
c = vtop->c.i;
|
||||
vpop();
|
||||
return c;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* parse an integer constant and return its value.
|
||||
Complain if it doesn't fit 32bit (signed or unsigned). */
|
||||
ST_FUNC int expr_const(void)
|
||||
{
|
||||
int c;
|
||||
#if HAVE_LONG_LONG
|
||||
int64_t wc = expr_const64();
|
||||
#else
|
||||
int32_t wc = expr_const32();
|
||||
#endif
|
||||
c = wc;
|
||||
if (c != wc && (unsigned)c != wc)
|
||||
tcc_error("constant exceeds 32 bit");
|
||||
|
@ -5444,8 +5600,13 @@ static void gfunc_return(CType *func_type)
|
|||
|
||||
static int case_cmp(const void *pa, const void *pb)
|
||||
{
|
||||
#if HAVE_LONG_LONG
|
||||
int64_t a = (*(struct case_t**) pa)->v1;
|
||||
int64_t b = (*(struct case_t**) pb)->v1;
|
||||
#else
|
||||
int32_t a = (*(struct case_t**) pa)->v1;
|
||||
int32_t b = (*(struct case_t**) pb)->v1;
|
||||
#endif
|
||||
return a < b ? -1 : a > b;
|
||||
}
|
||||
|
||||
|
@ -5770,10 +5931,18 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||
expect("switch");
|
||||
nocode_wanted &= ~0x20000000;
|
||||
next();
|
||||
#if HAVE_LONG_LONG
|
||||
cr->v1 = cr->v2 = expr_const64();
|
||||
#else
|
||||
cr->v1 = cr->v2 = expr_const32();
|
||||
#endif
|
||||
if (gnu_ext && tok == TOK_DOTS) {
|
||||
next();
|
||||
#if HAVE_LONG_LONG
|
||||
cr->v2 = expr_const64();
|
||||
#else
|
||||
cr->v2 = expr_const32();
|
||||
#endif
|
||||
if (cr->v2 < cr->v1)
|
||||
tcc_warning("empty case range");
|
||||
}
|
||||
|
@ -5938,7 +6107,11 @@ static void init_putz(Section *sec, unsigned long c, int size)
|
|||
if (sec) {
|
||||
/* nothing to do because globals are already set to zero */
|
||||
} else {
|
||||
#if BOOTSTRAP && __arm__
|
||||
vpush_global_sym(&func_old_type, TOK___memset);
|
||||
#else
|
||||
vpush_global_sym(&func_old_type, TOK_memset);
|
||||
#endif
|
||||
vseti(VT_LOCAL, c);
|
||||
#ifdef TCC_TARGET_ARM
|
||||
vpushs(size);
|
||||
|
@ -6068,6 +6241,15 @@ static int decl_designator(CType *type, Section *sec, unsigned long c,
|
|||
return al;
|
||||
}
|
||||
|
||||
#if BOOTSTRAP && HAVE_FLOAT
|
||||
struct long_double
|
||||
{
|
||||
int one;
|
||||
int two;
|
||||
int three;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* store a value or an expression directly in global data or in local array */
|
||||
static void init_putv(CType *type, Section *sec, unsigned long c)
|
||||
{
|
||||
|
@ -6177,20 +6359,49 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
|
|||
*(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
|
||||
break;
|
||||
case VT_FLOAT:
|
||||
#if HAVE_FLOAT
|
||||
#if !(BOOTSTRAP && __arm__)
|
||||
*(float*)ptr = vtop->c.f;
|
||||
#else
|
||||
{
|
||||
long *lptr = ptr;
|
||||
*lptr = vtop->c.f;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
case VT_DOUBLE:
|
||||
#if HAVE_FLOAT
|
||||
#if !(BOOTSTRAP && __arm__)
|
||||
*(double *)ptr = vtop->c.d;
|
||||
#else
|
||||
{
|
||||
long long *llptr = ptr;
|
||||
*llptr = vtop->c.d;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
case VT_LDOUBLE:
|
||||
#if HAVE_FLOAT
|
||||
if (sizeof(long double) == LDOUBLE_SIZE)
|
||||
#if !(BOOTSTRAP && __arm__)
|
||||
*(long double *)ptr = vtop->c.ld;
|
||||
#else
|
||||
{
|
||||
// XXX TODO: breaks on mescc/mes-tcc based build
|
||||
// maybe disable with HAVE_LONG_DOUBLE?
|
||||
//struct long_double *ldptr = ptr;
|
||||
//struct long_double tmp = (struct long_double)vtop->c.ld;
|
||||
//*ldptr = (struct long_double)tmp;
|
||||
}
|
||||
#endif
|
||||
else if (sizeof(double) == LDOUBLE_SIZE)
|
||||
*(double *)ptr = (double)vtop->c.ld;
|
||||
#if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
|
||||
else if (sizeof (long double) >= 10)
|
||||
memcpy(memset(ptr, 0, LDOUBLE_SIZE), &vtop->c.ld, 10);
|
||||
#ifdef __TINYC__
|
||||
#if defined (__TINYC__)
|
||||
else if (sizeof (long double) == sizeof (double))
|
||||
__asm__("fldl %1\nfstpt %0\n" : "=m"
|
||||
(memset(ptr, 0, LDOUBLE_SIZE), ptr) : "m" (vtop->c.ld));
|
||||
|
@ -6198,6 +6409,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
|
|||
#endif
|
||||
else
|
||||
tcc_error("can't cross compile long double constants");
|
||||
#endif
|
||||
break;
|
||||
#if PTR_SIZE != 8
|
||||
case VT_LLONG:
|
||||
|
|
2
tccpe.c
2
tccpe.c
|
@ -18,7 +18,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#define PE_MERGE_DATA
|
||||
/* #define PE_PRINT_SECTIONS */
|
||||
|
|
28
tccpp.c
28
tccpp.c
|
@ -18,7 +18,16 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#if BOOTSTRAP && __arm__
|
||||
void
|
||||
tccpp_ok ()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************************/
|
||||
/* global variables */
|
||||
|
@ -2171,6 +2180,10 @@ static void parse_number(const char *p)
|
|||
unsigned int bn[BN_SIZE];
|
||||
double d;
|
||||
|
||||
/* initialize values */
|
||||
d = 0;
|
||||
bn_zero(bn);
|
||||
|
||||
/* number */
|
||||
q = token_buf;
|
||||
ch = *p++;
|
||||
|
@ -2282,7 +2295,9 @@ static void parse_number(const char *p)
|
|||
|
||||
/* now we can generate the number */
|
||||
/* XXX: should patch directly float number */
|
||||
#if HAVE_FLOAT
|
||||
d = (double)bn[1] * 4294967296.0 + (double)bn[0];
|
||||
#endif
|
||||
d = ldexp(d, exp_val - frac_bits);
|
||||
t = toup(ch);
|
||||
if (t == 'F') {
|
||||
|
@ -2353,11 +2368,15 @@ static void parse_number(const char *p)
|
|||
tokc.d = strtod(token_buf, NULL);
|
||||
#else
|
||||
tok = TOK_CLDOUBLE;
|
||||
#if HAVE_FLOAT
|
||||
tokc.ld = strtold(token_buf, NULL);
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
tok = TOK_CDOUBLE;
|
||||
#if HAVE_FLOAT
|
||||
tokc.d = strtod(token_buf, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -2388,10 +2407,12 @@ static void parse_number(const char *p)
|
|||
tcc_error("invalid digit");
|
||||
n1 = n;
|
||||
n = n * b + t;
|
||||
#if HAVE_LONG_LONG
|
||||
/* detect overflow */
|
||||
/* XXX: this test is not reliable */
|
||||
if (n < n1)
|
||||
tcc_error("integer constant overflow");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Determine the characteristics (unsigned and/or 64bit) the type of
|
||||
|
@ -2421,11 +2442,14 @@ static void parse_number(const char *p)
|
|||
}
|
||||
}
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
/* Whether 64 bits are needed to hold the constant's value */
|
||||
if (n & 0xffffffff00000000LL || must_64bit) {
|
||||
tok = TOK_CLLONG;
|
||||
n1 = n >> 32;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
tok = TOK_CINT;
|
||||
n1 = n;
|
||||
}
|
||||
|
@ -3485,7 +3509,7 @@ ST_FUNC void preprocess_start(TCCState *s1)
|
|||
s1->pack_stack[0] = 0;
|
||||
s1->pack_stack_ptr = s1->pack_stack;
|
||||
|
||||
set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
|
||||
set_idnum('$', IS_ID); // Activate dollars-in-identifiers always
|
||||
set_idnum('.', (parse_flags & PARSE_FLAG_ASM_FILE) ? IS_ID : 0);
|
||||
|
||||
buf = tcc_malloc(3 + strlen(file->filename));
|
||||
|
|
23
tccrun.c
23
tccrun.c
|
@ -18,7 +18,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
/* only native compiler supports -run */
|
||||
#ifdef TCC_IS_NATIVE
|
||||
|
@ -271,7 +273,9 @@ static void set_pages_executable(void *ptr, unsigned long length)
|
|||
if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC))
|
||||
tcc_error("mprotect failed: did you mean to configure --with-selinux?");
|
||||
# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
|
||||
#if !BOOTSTRAP
|
||||
__clear_cache(ptr, (char *)ptr + length);
|
||||
#endif
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
@ -694,6 +698,25 @@ static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
|
|||
}
|
||||
}
|
||||
|
||||
#elif defined(__riscv)
|
||||
static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
|
||||
{
|
||||
// TODO make sure api matches
|
||||
if (level < 0) {
|
||||
return -1;
|
||||
} else if (level == 0) {
|
||||
*paddr = uc->uc_mcontext.__gregs[REG_PC];
|
||||
} else {
|
||||
addr_t *fp = (addr_t*)uc->uc_mcontext.__gregs[REG_S0]; // REG_S0 == 8
|
||||
while (--level && fp >= (addr_t*)0x1000)
|
||||
fp = (addr_t *)fp[-2];
|
||||
if (fp < (addr_t*)0x1000)
|
||||
return -1;
|
||||
*paddr = fp[-1];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
#else
|
||||
|
||||
|
|
18
tcctok.h
18
tcctok.h
|
@ -59,7 +59,7 @@
|
|||
DEF(TOK_ASM2, "__asm")
|
||||
DEF(TOK_ASM3, "__asm__")
|
||||
|
||||
#ifdef TCC_TARGET_ARM64
|
||||
#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
|
||||
DEF(TOK_UINT128, "__uint128_t")
|
||||
#endif
|
||||
|
||||
|
@ -144,6 +144,11 @@
|
|||
DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef TCC_TARGET_RISCV64
|
||||
DEF(TOK_builtin_va_start, "__builtin_va_start")
|
||||
#endif
|
||||
|
||||
DEF(TOK_REGPARM1, "regparm")
|
||||
DEF(TOK_REGPARM2, "__regparm__")
|
||||
|
||||
|
@ -167,6 +172,11 @@
|
|||
|
||||
/* builtin functions or variables */
|
||||
#ifndef TCC_ARM_EABI
|
||||
#if BOOTSTRAP && __arm__
|
||||
DEF(TOK___memcpy, "__memcpy")
|
||||
DEF(TOK___memmove, "__memmove")
|
||||
DEF(TOK___memset, "__memset")
|
||||
#endif
|
||||
DEF(TOK_memcpy, "memcpy")
|
||||
DEF(TOK_memmove, "memmove")
|
||||
DEF(TOK_memset, "memset")
|
||||
|
@ -252,7 +262,7 @@
|
|||
#if defined TCC_TARGET_PE
|
||||
DEF(TOK___chkstk, "__chkstk")
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM64
|
||||
#if defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
|
||||
DEF(TOK___arm64_clear_cache, "__arm64_clear_cache")
|
||||
DEF(TOK___addtf3, "__addtf3")
|
||||
DEF(TOK___subtf3, "__subtf3")
|
||||
|
@ -346,3 +356,7 @@
|
|||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||
#include "i386-tok.h"
|
||||
#endif
|
||||
|
||||
#if defined TCC_TARGET_RISCV64
|
||||
#include "riscv64-tok.h"
|
||||
#endif
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
//#define ARMAG "!<arch>\n"
|
||||
#define ARFMAG "`\n"
|
||||
|
@ -207,6 +209,9 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
|
|||
(sym->st_info == 0x10
|
||||
|| sym->st_info == 0x11
|
||||
|| sym->st_info == 0x12
|
||||
|| sym->st_info == 0x20
|
||||
|| sym->st_info == 0x21
|
||||
|| sym->st_info == 0x22
|
||||
)) {
|
||||
//printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name);
|
||||
istrlen = strlen(strtab + sym->st_name)+1;
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
export V
|
||||
if test "$V" = 1 -o "$V" = 2; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
arch=$(uname -m)
|
||||
case $arch in
|
||||
aarch*)
|
||||
cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
arm*|aarch*)
|
||||
cpu=arm
|
||||
tcc_cpu=arm
|
||||
triplet=arm-unknown-linux-gnueabihf
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
*)
|
||||
cpu=x86
|
||||
tcc_cpu=i386
|
||||
triplet=i686-unknown-linux-gnu
|
||||
cross_prefix=${triplet}-
|
||||
;;
|
||||
esac
|
||||
export cpu
|
||||
export cross_prefix
|
||||
export tcc_cpu
|
||||
export triplet
|
||||
|
||||
GCC_TCC=${GCC_TCC-./${cross_prefix}tcc}
|
||||
TCC=${TCC-./tcc}
|
||||
MES_PREFIX=${MES_PREFIX-mes}
|
||||
OBJDUMP=${OBJDUMP-objdump}
|
||||
DIFF=${DIFF-diff}
|
||||
|
||||
unset C_INCLUDE_PATH LIBRARY_PATH
|
||||
|
||||
if test "$tcc_cpu" = i386; then
|
||||
libtcc1=-ltcc1
|
||||
elif test "$tcc_cpu" = arm; then
|
||||
libtcc1='-lc -ltcc1 -ltcc1-mes'
|
||||
libtcc1=
|
||||
elif test "$tcc_cpu" = x86_64; then
|
||||
libtcc1=-ltcc1
|
||||
else
|
||||
echo "cpu not supported: $mes_cpu"
|
||||
fi
|
||||
|
||||
timeout=${timeout-timeout 5}
|
||||
if ! $timeout echo; then
|
||||
timeout=
|
||||
fi
|
||||
|
||||
t=${1-lib/tests/scaffold/t.c}
|
||||
b=$(dirname "$t")/$(basename "$t" .c)
|
||||
co="$b"-$triplet-tcc
|
||||
mo="$b"-mes-tcc
|
||||
|
||||
o="$co"
|
||||
|
||||
rm -f 1 1.s 1.link
|
||||
rm -f 2 2.s 2.link
|
||||
rm -f "$co" "$co".1
|
||||
rm -f "$mo" "$mo".1
|
||||
|
||||
r=0
|
||||
if [ -x $GCC_TCC ]; then
|
||||
$GCC_TCC \
|
||||
-c \
|
||||
-g \
|
||||
-nostdlib \
|
||||
-I $MES_PREFIX/include \
|
||||
-I $MES_PREFIX/scaffold/tinycc \
|
||||
-o "$o".o \
|
||||
"$t" \
|
||||
2> 1
|
||||
$GCC_TCC \
|
||||
-g \
|
||||
-L . \
|
||||
-o "$o" \
|
||||
"$o".o \
|
||||
-lc \
|
||||
$libtcc1 \
|
||||
2> 1.link
|
||||
set +e
|
||||
d=$(dirname "$t")
|
||||
d=$(dirname "$d")
|
||||
if [ "$d" = lib/tests ]; then
|
||||
$timeout "$o" -s --long file0 file1 > "$o".1
|
||||
else
|
||||
$timeout "$o" arg1 arg2 arg3 arg4 arg5 > "$o".1
|
||||
fi
|
||||
m=$?
|
||||
set -e
|
||||
[ -f "$b".exit ] && r=$(cat "$b".exit)
|
||||
[ $m = $r ]
|
||||
if [ -f "$b".expect ]; then
|
||||
$DIFF -ub "$b".expect "$o".1;
|
||||
fi
|
||||
fi
|
||||
|
||||
o="$b"-mes-tcc
|
||||
$TCC \
|
||||
-c \
|
||||
-g \
|
||||
-nostdlib \
|
||||
-I $MES_PREFIX/include \
|
||||
-I $MES_PREFIX/scaffold/tinycc \
|
||||
-o "$o".o \
|
||||
"$t" \
|
||||
2> 2
|
||||
$TCC \
|
||||
-g \
|
||||
-L . \
|
||||
-o "$o" \
|
||||
"$o".o \
|
||||
-lc \
|
||||
$libtcc1 \
|
||||
2> 2.link
|
||||
|
||||
set +e
|
||||
d=$(dirname "$t")
|
||||
d=$(dirname "$d")
|
||||
if [ "$d" = lib/tests ]; then
|
||||
$timeout "$o" -s --long file0 file1 > "$o".1
|
||||
else
|
||||
$timeout "$o" arg1 arg2 arg3 arg4 arg5 > "$o".1
|
||||
fi
|
||||
m=$?
|
||||
|
||||
set -e
|
||||
[ $m = $r ]
|
||||
[ -f "$b".exit ] && r=$(cat "$b".exit)
|
||||
if [ -f "$b".expect ]; then
|
||||
$DIFF -ub "$b".expect "$co".1;
|
||||
$DIFF -ub "$co".1 "$mo".1;
|
||||
fi
|
|
@ -237,6 +237,7 @@ cross-test :
|
|||
$(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
|
||||
$(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
|
||||
$(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
|
||||
$(TOP)/riscv64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
|
||||
$(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
|
||||
$(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
|
||||
$(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
|
||||
|
|
|
@ -3698,8 +3698,10 @@ void builtin_frame_address_test(void)
|
|||
char *fp0 = __builtin_frame_address(0);
|
||||
|
||||
printf("str: %s\n", str);
|
||||
#ifndef __riscv // gcc dumps core. tcc, clang work
|
||||
bfa1(str-fp0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
char via_volatile (char i)
|
||||
|
|
|
@ -1,568 +0,0 @@
|
|||
/*
|
||||
* The information in this document is subject to change
|
||||
* without notice and should not be construed as a commitment
|
||||
* by Digital Equipment Corporation or by DECUS.
|
||||
*
|
||||
* Neither Digital Equipment Corporation, DECUS, nor the authors
|
||||
* assume any responsibility for the use or reliability of this
|
||||
* document or the described software.
|
||||
*
|
||||
* Copyright (C) 1980, DECUS
|
||||
*
|
||||
* General permission to copy or modify, but not for profit, is
|
||||
* hereby granted, provided that the above copyright notice is
|
||||
* included and reference made to the fact that reproduction
|
||||
* privileges were granted by DECUS.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h> // tolower()
|
||||
|
||||
/*
|
||||
* grep
|
||||
*
|
||||
* Runs on the Decus compiler or on vms, On vms, define as:
|
||||
* grep :== "$disk:[account]grep" (native)
|
||||
* grep :== "$disk:[account]grep grep" (Decus)
|
||||
* See below for more information.
|
||||
*/
|
||||
|
||||
char *documentation[] = {
|
||||
"grep searches a file for a given pattern. Execute by",
|
||||
" grep [flags] regular_expression file_list\n",
|
||||
"Flags are single characters preceded by '-':",
|
||||
" -c Only a count of matching lines is printed",
|
||||
" -f Print file name for matching lines switch, see below",
|
||||
" -n Each line is preceded by its line number",
|
||||
" -v Only print non-matching lines\n",
|
||||
"The file_list is a list of files (wildcards are acceptable on RSX modes).",
|
||||
"\nThe file name is normally printed if there is a file given.",
|
||||
"The -f flag reverses this action (print name no file, not if more).\n",
|
||||
0 };
|
||||
|
||||
char *patdoc[] = {
|
||||
"The regular_expression defines the pattern to search for. Upper- and",
|
||||
"lower-case are always ignored. Blank lines never match. The expression",
|
||||
"should be quoted to prevent file-name translation.",
|
||||
"x An ordinary character (not mentioned below) matches that character.",
|
||||
"'\\' The backslash quotes any character. \"\\$\" matches a dollar-sign.",
|
||||
"'^' A circumflex at the beginning of an expression matches the",
|
||||
" beginning of a line.",
|
||||
"'$' A dollar-sign at the end of an expression matches the end of a line.",
|
||||
"'.' A period matches any character except \"new-line\".",
|
||||
"':a' A colon matches a class of characters described by the following",
|
||||
"':d' character. \":a\" matches any alphabetic, \":d\" matches digits,",
|
||||
"':n' \":n\" matches alphanumerics, \": \" matches spaces, tabs, and",
|
||||
"': ' other control characters, such as new-line.",
|
||||
"'*' An expression followed by an asterisk matches zero or more",
|
||||
" occurrences of that expression: \"fo*\" matches \"f\", \"fo\"",
|
||||
" \"foo\", etc.",
|
||||
"'+' An expression followed by a plus sign matches one or more",
|
||||
" occurrences of that expression: \"fo+\" matches \"fo\", etc.",
|
||||
"'-' An expression followed by a minus sign optionally matches",
|
||||
" the expression.",
|
||||
"'[]' A string enclosed in square brackets matches any character in",
|
||||
" that string, but no others. If the first character in the",
|
||||
" string is a circumflex, the expression matches any character",
|
||||
" except \"new-line\" and the characters in the string. For",
|
||||
" example, \"[xyz]\" matches \"xx\" and \"zyx\", while \"[^xyz]\"",
|
||||
" matches \"abc\" but not \"axb\". A range of characters may be",
|
||||
" specified by two characters separated by \"-\". Note that,",
|
||||
" [a-z] matches alphabetics, while [z-a] never matches.",
|
||||
"The concatenation of regular expressions is a regular expression.",
|
||||
0};
|
||||
|
||||
#define LMAX 512
|
||||
#define PMAX 256
|
||||
|
||||
#define CHAR 1
|
||||
#define BOL 2
|
||||
#define EOL 3
|
||||
#define ANY 4
|
||||
#define CLASS 5
|
||||
#define NCLASS 6
|
||||
#define STAR 7
|
||||
#define PLUS 8
|
||||
#define MINUS 9
|
||||
#define ALPHA 10
|
||||
#define DIGIT 11
|
||||
#define NALPHA 12
|
||||
#define PUNCT 13
|
||||
#define RANGE 14
|
||||
#define ENDPAT 15
|
||||
|
||||
int cflag=0, fflag=0, nflag=0, vflag=0, nfile=0, debug=0;
|
||||
|
||||
char *pp, lbuf[LMAX], pbuf[PMAX];
|
||||
|
||||
char *cclass();
|
||||
char *pmatch();
|
||||
void store(int);
|
||||
void error(char *);
|
||||
void badpat(char *, char *, char *);
|
||||
int match(void);
|
||||
|
||||
|
||||
/*** Display a file name *******************************/
|
||||
void file(char *s)
|
||||
{
|
||||
printf("File %s:\n", s);
|
||||
}
|
||||
|
||||
/*** Report unopenable file ****************************/
|
||||
void cant(char *s)
|
||||
{
|
||||
fprintf(stderr, "%s: cannot open\n", s);
|
||||
}
|
||||
|
||||
/*** Give good help ************************************/
|
||||
void help(char **hp)
|
||||
{
|
||||
char **dp;
|
||||
|
||||
for (dp = hp; *dp; ++dp)
|
||||
printf("%s\n", *dp);
|
||||
}
|
||||
|
||||
/*** Display usage summary *****************************/
|
||||
void usage(char *s)
|
||||
{
|
||||
fprintf(stderr, "?GREP-E-%s\n", s);
|
||||
fprintf(stderr,
|
||||
"Usage: grep [-cfnv] pattern [file ...]. grep ? for help\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*** Compile the pattern into global pbuf[] ************/
|
||||
void compile(char *source)
|
||||
{
|
||||
char *s; /* Source string pointer */
|
||||
char *lp; /* Last pattern pointer */
|
||||
int c; /* Current character */
|
||||
int o; /* Temp */
|
||||
char *spp; /* Save beginning of pattern */
|
||||
|
||||
s = source;
|
||||
if (debug)
|
||||
printf("Pattern = \"%s\"\n", s);
|
||||
pp = pbuf;
|
||||
while (c = *s++) {
|
||||
/*
|
||||
* STAR, PLUS and MINUS are special.
|
||||
*/
|
||||
if (c == '*' || c == '+' || c == '-') {
|
||||
if (pp == pbuf ||
|
||||
(o=pp[-1]) == BOL ||
|
||||
o == EOL ||
|
||||
o == STAR ||
|
||||
o == PLUS ||
|
||||
o == MINUS)
|
||||
badpat("Illegal occurrence op.", source, s);
|
||||
store(ENDPAT);
|
||||
store(ENDPAT);
|
||||
spp = pp; /* Save pattern end */
|
||||
while (--pp > lp) /* Move pattern down */
|
||||
*pp = pp[-1]; /* one byte */
|
||||
*pp = (c == '*') ? STAR :
|
||||
(c == '-') ? MINUS : PLUS;
|
||||
pp = spp; /* Restore pattern end */
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* All the rest.
|
||||
*/
|
||||
lp = pp; /* Remember start */
|
||||
switch(c) {
|
||||
|
||||
case '^':
|
||||
store(BOL);
|
||||
break;
|
||||
|
||||
case '$':
|
||||
store(EOL);
|
||||
break;
|
||||
|
||||
case '.':
|
||||
store(ANY);
|
||||
break;
|
||||
|
||||
case '[':
|
||||
s = cclass(source, s);
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if (*s) {
|
||||
switch(tolower(c = *s++)) {
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
store(ALPHA);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'D':
|
||||
store(DIGIT);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'N':
|
||||
store(NALPHA);
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
store(PUNCT);
|
||||
break;
|
||||
|
||||
default:
|
||||
badpat("Unknown : type", source, s);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
else badpat("No : type", source, s);
|
||||
|
||||
case '\\':
|
||||
if (*s)
|
||||
c = *s++;
|
||||
|
||||
default:
|
||||
store(CHAR);
|
||||
store(tolower(c));
|
||||
}
|
||||
}
|
||||
store(ENDPAT);
|
||||
store(0); /* Terminate string */
|
||||
if (debug) {
|
||||
for (lp = pbuf; lp < pp;) {
|
||||
if ((c = (*lp++ & 0377)) < ' ')
|
||||
printf("\\%o ", c);
|
||||
else printf("%c ", c);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*** Compile a class (within []) ***********************/
|
||||
char *cclass(char *source, char *src)
|
||||
/* char *source; // Pattern start -- for error msg. */
|
||||
/* char *src; // Class start */
|
||||
{
|
||||
char *s; /* Source pointer */
|
||||
char *cp; /* Pattern start */
|
||||
int c; /* Current character */
|
||||
int o; /* Temp */
|
||||
|
||||
s = src;
|
||||
o = CLASS;
|
||||
if (*s == '^') {
|
||||
++s;
|
||||
o = NCLASS;
|
||||
}
|
||||
store(o);
|
||||
cp = pp;
|
||||
store(0); /* Byte count */
|
||||
while ((c = *s++) && c!=']') {
|
||||
if (c == '\\') { /* Store quoted char */
|
||||
if ((c = *s++) == '\0') /* Gotta get something */
|
||||
badpat("Class terminates badly", source, s);
|
||||
else store(tolower(c));
|
||||
}
|
||||
else if (c == '-' &&
|
||||
(pp - cp) > 1 && *s != ']' && *s != '\0') {
|
||||
c = pp[-1]; /* Range start */
|
||||
pp[-1] = RANGE; /* Range signal */
|
||||
store(c); /* Re-store start */
|
||||
c = *s++; /* Get end char and*/
|
||||
store(tolower(c)); /* Store it */
|
||||
}
|
||||
else {
|
||||
store(tolower(c)); /* Store normal char */
|
||||
}
|
||||
}
|
||||
if (c != ']')
|
||||
badpat("Unterminated class", source, s);
|
||||
if ((c = (pp - cp)) >= 256)
|
||||
badpat("Class too large", source, s);
|
||||
if (c == 0)
|
||||
badpat("Empty class", source, s);
|
||||
*cp = c;
|
||||
return(s);
|
||||
}
|
||||
|
||||
/*** Store an entry in the pattern buffer **************/
|
||||
void store(int op)
|
||||
{
|
||||
if (pp >= &pbuf[PMAX])
|
||||
error("Pattern too complex\n");
|
||||
*pp++ = op;
|
||||
}
|
||||
|
||||
/*** Report a bad pattern specification ****************/
|
||||
void badpat(char *message, char *source, char *stop)
|
||||
/* char *message; // Error message */
|
||||
/* char *source; // Pattern start */
|
||||
/* char *stop; // Pattern end */
|
||||
{
|
||||
fprintf(stderr, "-GREP-E-%s, pattern is\"%s\"\n", message, source);
|
||||
fprintf(stderr, "-GREP-E-Stopped at byte %ld, '%c'\n",
|
||||
stop-source, stop[-1]);
|
||||
error("?GREP-E-Bad pattern\n");
|
||||
}
|
||||
|
||||
/*** Scan the file for the pattern in pbuf[] ***********/
|
||||
void grep(FILE *fp, char *fn)
|
||||
/* FILE *fp; // File to process */
|
||||
/* char *fn; // File name (for -f option) */
|
||||
{
|
||||
int lno, count, m;
|
||||
|
||||
lno = 0;
|
||||
count = 0;
|
||||
while (fgets(lbuf, LMAX, fp)) {
|
||||
++lno;
|
||||
m = match();
|
||||
if ((m && !vflag) || (!m && vflag)) {
|
||||
++count;
|
||||
if (!cflag) {
|
||||
if (fflag && fn) {
|
||||
file(fn);
|
||||
fn = 0;
|
||||
}
|
||||
if (nflag)
|
||||
printf("%d\t", lno);
|
||||
printf("%s\n", lbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cflag) {
|
||||
if (fflag && fn)
|
||||
file(fn);
|
||||
printf("%d\n", count);
|
||||
}
|
||||
}
|
||||
|
||||
/*** Match line (lbuf) with pattern (pbuf) return 1 if match ***/
|
||||
int match()
|
||||
{
|
||||
char *l; /* Line pointer */
|
||||
|
||||
for (l = lbuf; *l; ++l) {
|
||||
if (pmatch(l, pbuf))
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*** Match partial line with pattern *******************/
|
||||
char *pmatch(char *line, char *pattern)
|
||||
/* char *line; // (partial) line to match */
|
||||
/* char *pattern; // (partial) pattern to match */
|
||||
{
|
||||
char *l; /* Current line pointer */
|
||||
char *p; /* Current pattern pointer */
|
||||
char c; /* Current character */
|
||||
char *e; /* End for STAR and PLUS match */
|
||||
int op; /* Pattern operation */
|
||||
int n; /* Class counter */
|
||||
char *are; /* Start of STAR match */
|
||||
|
||||
l = line;
|
||||
if (debug > 1)
|
||||
printf("pmatch(\"%s\")\n", line);
|
||||
p = pattern;
|
||||
while ((op = *p++) != ENDPAT) {
|
||||
if (debug > 1)
|
||||
printf("byte[%ld] = 0%o, '%c', op = 0%o\n",
|
||||
l-line, *l, *l, op);
|
||||
switch(op) {
|
||||
|
||||
case CHAR:
|
||||
if (tolower(*l++) != *p++)
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case BOL:
|
||||
if (l != lbuf)
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case EOL:
|
||||
if (*l != '\0')
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case ANY:
|
||||
if (*l++ == '\0')
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case DIGIT:
|
||||
if ((c = *l++) < '0' || (c > '9'))
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case ALPHA:
|
||||
c = tolower(*l++);
|
||||
if (c < 'a' || c > 'z')
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case NALPHA:
|
||||
c = tolower(*l++);
|
||||
if (c >= 'a' && c <= 'z')
|
||||
break;
|
||||
else if (c < '0' || c > '9')
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case PUNCT:
|
||||
c = *l++;
|
||||
if (c == 0 || c > ' ')
|
||||
return(0);
|
||||
break;
|
||||
|
||||
case CLASS:
|
||||
case NCLASS:
|
||||
c = tolower(*l++);
|
||||
n = *p++ & 0377;
|
||||
do {
|
||||
if (*p == RANGE) {
|
||||
p += 3;
|
||||
n -= 2;
|
||||
if (c >= p[-2] && c <= p[-1])
|
||||
break;
|
||||
}
|
||||
else if (c == *p++)
|
||||
break;
|
||||
} while (--n > 1);
|
||||
if ((op == CLASS) == (n <= 1))
|
||||
return(0);
|
||||
if (op == CLASS)
|
||||
p += n - 2;
|
||||
break;
|
||||
|
||||
case MINUS:
|
||||
e = pmatch(l, p); /* Look for a match */
|
||||
while (*p++ != ENDPAT); /* Skip over pattern */
|
||||
if (e) /* Got a match? */
|
||||
l = e; /* Yes, update string */
|
||||
break; /* Always succeeds */
|
||||
|
||||
case PLUS: /* One or more ... */
|
||||
if ((l = pmatch(l, p)) == 0)
|
||||
return(0); /* Gotta have a match */
|
||||
case STAR: /* Zero or more ... */
|
||||
are = l; /* Remember line start */
|
||||
while (*l && (e = pmatch(l, p)))
|
||||
l = e; /* Get longest match */
|
||||
while (*p++ != ENDPAT); /* Skip over pattern */
|
||||
while (l >= are) { /* Try to match rest */
|
||||
if (e = pmatch(l, p))
|
||||
return(e);
|
||||
--l; /* Nope, try earlier */
|
||||
}
|
||||
return(0); /* Nothing else worked */
|
||||
|
||||
default:
|
||||
printf("Bad op code %d\n", op);
|
||||
error("Cannot happen -- match\n");
|
||||
}
|
||||
}
|
||||
return(l);
|
||||
}
|
||||
|
||||
/*** Report an error ***********************************/
|
||||
void error(char *s)
|
||||
{
|
||||
fprintf(stderr, "%s", s);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*** Main program - parse arguments & grep *************/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *p;
|
||||
int c, i;
|
||||
int gotpattern;
|
||||
|
||||
FILE *f;
|
||||
|
||||
if (argc <= 1)
|
||||
usage("No arguments");
|
||||
if (argc == 2 && argv[1][0] == '?' && argv[1][1] == 0) {
|
||||
help(documentation);
|
||||
help(patdoc);
|
||||
return 0;
|
||||
}
|
||||
nfile = argc-1;
|
||||
gotpattern = 0;
|
||||
for (i=1; i < argc; ++i) {
|
||||
p = argv[i];
|
||||
if (*p == '-') {
|
||||
++p;
|
||||
while (c = *p++) {
|
||||
switch(tolower(c)) {
|
||||
|
||||
case '?':
|
||||
help(documentation);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'c':
|
||||
++cflag;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
case 'd':
|
||||
++debug;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
case 'f':
|
||||
++fflag;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'N':
|
||||
++nflag;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
case 'V':
|
||||
++vflag;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage("Unknown flag");
|
||||
}
|
||||
}
|
||||
argv[i] = 0;
|
||||
--nfile;
|
||||
} else if (!gotpattern) {
|
||||
compile(p);
|
||||
argv[i] = 0;
|
||||
++gotpattern;
|
||||
--nfile;
|
||||
}
|
||||
}
|
||||
if (!gotpattern)
|
||||
usage("No pattern");
|
||||
if (nfile == 0)
|
||||
grep(stdin, 0);
|
||||
else {
|
||||
fflag = fflag ^ (nfile > 0);
|
||||
for (i=1; i < argc; ++i) {
|
||||
if (p = argv[i]) {
|
||||
if ((f=fopen(p, "r")) == NULL)
|
||||
cant(p);
|
||||
else {
|
||||
grep(f, p);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
|
|
@ -1,3 +0,0 @@
|
|||
File 46_grep.c:
|
||||
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
|
||||
|
20
x86_64-gen.c
20
x86_64-gen.c
|
@ -1032,15 +1032,15 @@ static void gadd_sp(int val)
|
|||
}
|
||||
}
|
||||
|
||||
typedef enum X86_64_Mode {
|
||||
enum {
|
||||
x86_64_mode_none,
|
||||
x86_64_mode_memory,
|
||||
x86_64_mode_integer,
|
||||
x86_64_mode_sse,
|
||||
x86_64_mode_x87
|
||||
} X86_64_Mode;
|
||||
};
|
||||
|
||||
static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b)
|
||||
static int classify_x86_64_merge(int a, int b)
|
||||
{
|
||||
if (a == b)
|
||||
return a;
|
||||
|
@ -1058,9 +1058,9 @@ static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b)
|
|||
return x86_64_mode_sse;
|
||||
}
|
||||
|
||||
static X86_64_Mode classify_x86_64_inner(CType *ty)
|
||||
static int classify_x86_64_inner(CType *ty)
|
||||
{
|
||||
X86_64_Mode mode;
|
||||
int mode;
|
||||
Sym *f;
|
||||
|
||||
switch (ty->t & VT_BTYPE) {
|
||||
|
@ -1093,9 +1093,9 @@ static X86_64_Mode classify_x86_64_inner(CType *ty)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
|
||||
static int classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
|
||||
{
|
||||
X86_64_Mode mode;
|
||||
int mode;
|
||||
int size, align, ret_t = 0;
|
||||
|
||||
if (ty->t & (VT_BITFIELD|VT_ARRAY)) {
|
||||
|
@ -1158,7 +1158,7 @@ ST_FUNC int classify_x86_64_va_arg(CType *ty)
|
|||
__va_gen_reg, __va_float_reg, __va_stack
|
||||
};
|
||||
int size, align, reg_count;
|
||||
X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, ®_count);
|
||||
int mode = classify_x86_64_arg(ty, NULL, &size, &align, ®_count);
|
||||
switch (mode) {
|
||||
default: return __va_stack;
|
||||
case x86_64_mode_integer: return __va_gen_reg;
|
||||
|
@ -1194,7 +1194,7 @@ static int arg_prepare_reg(int idx) {
|
|||
parameters and the function address. */
|
||||
void gfunc_call(int nb_args)
|
||||
{
|
||||
X86_64_Mode mode;
|
||||
int mode;
|
||||
CType type;
|
||||
int size, align, r, args_size, stack_adjust, run_start, run_end, i, reg_count;
|
||||
int nb_reg_args = 0;
|
||||
|
@ -1483,7 +1483,7 @@ static void push_arg_reg(int i) {
|
|||
/* generate function prolog of type 't' */
|
||||
void gfunc_prolog(CType *func_type)
|
||||
{
|
||||
X86_64_Mode mode;
|
||||
int mode;
|
||||
int i, addr, align, size, reg_count;
|
||||
int param_addr = 0, reg_param_index, sse_param_index;
|
||||
Sym *sym;
|
||||
|
|
Loading…
Reference in New Issue