Compare commits

...

53 Commits

Author SHA1 Message Date
Jan (janneke) Nieuwenhuizen 1b4f281ffc
Add ROADMAP.
TODO
  - setjmp
  - possibly: commented-out HAVE_FLOAT? in tccgen.c
  - integrate ARM ./bootstrap.sh build into commencement.scm
    + build gcc-2.95.3 ...etc, etc.

DONE:

  - ./pre-inst-env guix build --system=armhf-linux -e tcc-boot
  - mes-tcc can be bootstrapped, build and and rebuild itself, until
    boot6-tcc, with long longs and floats
2021-11-16 17:37:46 +01:00
Jan (janneke) Nieuwenhuizen 5fecf71b67
Revert "HACK bootstrap with arm-unknown-linux-gnueabihf-gcc."
This reverts commit c173a80c284d11f4ade5e6b6fa402a22f78bba9f.
2021-12-12 10:45:52 +01:00
Jan (janneke) Nieuwenhuizen 81125144c8
Revert "build-32.sh: Save bootX intermediate results."
This reverts commit af9ef83a3dc59f9456bedeb056fdf8e7d895e6e8.
2021-12-12 10:45:49 +01:00
Jan (janneke) Nieuwenhuizen 8bb4686809
build-32.sh: Save bootX intermediate results. 2021-12-09 12:29:48 +01:00
Jan (janneke) Nieuwenhuizen e879dabc84
HACK bootstrap with arm-unknown-linux-gnueabihf-gcc. 2021-12-05 20:39:57 +01:00
Jan (janneke) Nieuwenhuizen 13faf8acdb
HACK bootstrappable: ARM: "tccgen_ok". 2021-12-05 10:36:56 +01:00
Jan (janneke) Nieuwenhuizen ae201e2da8
HACK bootstrappable: ARM: "tccpp_ok". 2021-12-20 08:20:26 +01:00
Jan (janneke) Nieuwenhuizen b17abf12ef
build: Support building on Guix aarch64-linux. 2021-12-17 21:59:50 +01:00
Jan (janneke) Nieuwenhuizen 985d372400
doc: Update 'README'. 2021-12-21 08:33:46 +01:00
Jan (janneke) Nieuwenhuizen 52a29ab6f5
build: Add support for ARM.
* doit,
bootstrap.sh,
build.sh,
cc.sh: Update and add support for ARM.
* build-x86.sh: Likewise.  Rename to ...
* build-32.sh: ... this.
.gitignore: Remove test output.
2020-08-23 08:37:35 +02:00
Jan (janneke) Nieuwenhuizen b3ee5ea9de
Revert "lotsa debug printing."
This reverts commit 18a9e45500cdaf8dbb34aaab7a4753062a949af6.
2021-12-05 11:20:59 +01:00
Jan (janneke) Nieuwenhuizen ac3e85a317
Revert "lotsa debug printing: reduce"
This reverts commit 412a9bbfc7d041fda021a86853930b3a90374458.
2021-12-05 11:20:56 +01:00
Jan (janneke) Nieuwenhuizen 107521e1b2
lotsa debug printing: reduce 2021-11-15 09:51:27 +01:00
Jan Nieuwenhuizen 2f8a3df88e
lotsa debug printing. 2018-09-30 19:53:44 +02:00
Jan (janneke) Nieuwenhuizen fedd47f0ef
ARM: allow fake asm in functions. 2021-12-06 15:07:25 +01:00
Jan (janneke) Nieuwenhuizen ec24c7801c
bootstrappable: ARM: Force eabi header. 2021-12-20 12:23:28 +01:00
Jan (janneke) Nieuwenhuizen c7e1ef14e5
bootstrappable: HAVE_LONG_LONG, part 3. 2021-12-21 08:18:34 +01:00
Jan (janneke) Nieuwenhuizen 50b5eaeda9
bootstrappable: ARM: HAVE_FLOAT? 2021-12-05 13:21:22 +01:00
Jan (janneke) Nieuwenhuizen 6c6adc6301
bootstrappable: ARM: generate __memcpy, __memmove, __memset.
* tccgen.c (vstore)[BOOTSTRAP && __arm__]: Generate TOK__memove.
(init_putz): Generate TOK__memset.
* tcctok.h[BOOTSTRAP && __arm__]: Add __memcpy, __memmove, __memset.
2021-11-28 20:55:01 +01:00
Jan (janneke) Nieuwenhuizen 93f8a7fcd6
bootstrappable: ARM: HAVE_SETJMP. 2021-11-29 13:08:46 +01:00
Jan (janneke) Nieuwenhuizen f35ddb111e
bootstrappable: HAVE_LONG_LONG_STUB. 2021-12-10 22:48:12 +01:00
Jan (janneke) Nieuwenhuizen 9d88013991
bootstrappable: HAVE_LONG_LONG, part 2. 2021-11-25 21:13:35 +01:00
Jan (janneke) Nieuwenhuizen 94b62e27d9
bootstrappable: ARM: HAVE_FLOAT. 2021-12-05 13:44:07 +01:00
Jan (janneke) Nieuwenhuizen 7b5d1754d3
bootstrappable: ARM: Avoid ternary. 2021-12-06 11:47:49 +01:00
Jan (janneke) Nieuwenhuizen c5c1d6ee70
bootstrappable: ARM: Avoid ternary in argument.
This avoids depending on "70-ternary-arithmetic-argument.c"

* arm-gen.c (gcall_or_jmp): Split calculation and call.
2021-11-15 21:26:20 +01:00
Jan (janneke) Nieuwenhuizen 1a21e8a6ab
bootstrappable: ARM: HAVE_FLOAT. 2021-11-15 12:07:14 +01:00
Jan (janneke) Nieuwenhuizen e23023ec8a
bootstrappable: HAVE_FLOAT, part 2. 2020-12-16 14:28:49 +01:00
Jan (janneke) Nieuwenhuizen 907479d7ff
bootstrappable: Avoid function modulo. 2020-12-13 14:53:32 +01:00
Jan (janneke) Nieuwenhuizen 33403a4011
bootstrappable: Avoid using __clear_cache. 2020-12-13 14:53:31 +01:00
Jan (janneke) Nieuwenhuizen 94fa1710aa
bootstrappable: Use tmp initialization instead of for struct assigment. 2020-12-13 14:53:31 +01:00
Jan (janneke) Nieuwenhuizen 35ccd60989
bootstrappable: Support libtcc1-mes.a. 2020-12-13 14:53:31 +01:00
Jan (janneke) Nieuwenhuizen 0334950c24
Revert "bootstrappable: Handle libtcc1.a."
This reverts commit 274bd060fd.
2020-12-13 14:53:31 +01:00
Jan Nieuwenhuizen 20b1a1d001
README: Update to add info about GNU Mes and bootstrappable-tinycc.
* README: Add header on GNU Mes and bootstrappable-tinycc.
2020-02-22 16:31:24 +01:00
Jan Nieuwenhuizen 6e62e0e58b
makefile: Add dist target.
* Makefile (dist): Create reproducible tarball.
2019-11-17 12:06:06 +01:00
Jan Nieuwenhuizen 17df781f70
Revert "lotsa debug printing."
This reverts commit 09cecc93442f2f3b7dbd1bb5faf18b41f42103ff.
2019-10-10 22:40:48 +02:00
Jan Nieuwenhuizen ba1c47dbdb
lotsa debug printing. 2019-10-10 22:40:47 +02:00
Jan Nieuwenhuizen 0585122eb1
build: Update for mes-0.21. 2019-10-10 22:40:47 +02:00
Jan Nieuwenhuizen f90808b155
build: Update for mes-0.20. 2019-04-06 14:16:30 +02:00
Jan Nieuwenhuizen 1063d5a0dc
bootstrappable: Update tccelf.c for mes-0.20. 2019-04-05 14:13:05 +02:00
Jan Nieuwenhuizen 36c0af218f
build: Support gash. 2019-04-04 21:46:55 +02:00
Jan Nieuwenhuizen ec63de4990
test: run tests/tests2 tests. 2019-04-04 21:46:55 +02:00
Jan Nieuwenhuizen cee58e0963
build: Support building from bootstrap-mes. 2019-04-04 21:46:54 +02:00
Jan Nieuwenhuizen 39de35689e
bootstrappable: Force static link. 2019-04-04 21:46:54 +02:00
Jan Nieuwenhuizen 2b6271d1d5
bootstrappable: Work around MesCC bug.
* tccelf.c (squeeze_multi_relocs): Simplify expressions.
2019-04-04 21:46:54 +02:00
Jan Nieuwenhuizen 379c62d63f
bootstrappable: add tcc.h include guards to include location. 2019-04-04 21:46:54 +02:00
Jan Nieuwenhuizen 274bd060fd
bootstrappable: Handle libtcc1.a. 2018-10-04 09:07:18 +02:00
Jan Nieuwenhuizen 6ae9aa40c7
bootstrappable: Skip tidy_section_headers.
* tccelf.c (elf_output_file)[BOOTSTRAPPABLE]: Skip tidy_section_headers.
2018-10-04 09:07:18 +02:00
Jan Nieuwenhuizen a130ce1702
bootstrappable: HAVE_FLOAT. 2018-10-04 09:07:17 +02:00
Jan Nieuwenhuizen de906df43a
bootstrappable: HAVE_BITFIELD. 2018-10-04 09:07:17 +02:00
Jan Nieuwenhuizen 540ba0b456
bootstrappable: HAVE_LONG_LONG.
* tccpp.c (parse_number)[!HAVE_LONG_LONG]: Skip overflow test.  Do not
  set TOK_CCLONG.
2018-10-04 09:07:17 +02:00
Jan Nieuwenhuizen 306f6779ad
bootstrappable: Work around Nyacc-0.80.42 bug.
* tccgen.c (update_storage)[__MESC__]: Work around Nyacc-0.80.42 bug.
2018-10-04 09:07:17 +02:00
Jan Nieuwenhuizen 9c97705c42
build: bootstrap build scripts.
* bootstrap.sh: New file.
* build.sh: New file.
* check.sh: New file.
* doit: New file.
* install.sh: New file.
* test.sh: New file.
2018-10-04 09:07:17 +02:00
Jan Nieuwenhuizen 584478fca2
bootstrappable: Remove non-free grep test.
* tests/tests2/46_grep.c: Remove non-free grep code.
* tests/tests2/46_grep.expect: Remove.
2018-09-18 07:27:57 +02:00
38 changed files with 2816 additions and 591 deletions

1
.gitignore vendored
View File

@ -54,3 +54,4 @@ tests/libtcc_test
tests/vla_test
tests/hello
tests/tests2/fred.txt
tests/tests2/*.1

8
BOOT Normal file
View File

@ -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

View File

@ -188,7 +188,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 +390,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
View File

@ -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
-----------------------------------------------------------------------

220
ROADMAP Normal file

File diff suppressed because one or more lines are too long

View File

@ -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)

View File

@ -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 */

241
boot.sh Executable file
View File

@ -0,0 +1,241 @@
#! /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}-
;;
*)
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"
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
cp -f libtcc1.a $prefix/lib/tcc
fi
echo "boot.sh: done"

257
bootstrap.sh Executable file
View File

@ -0,0 +1,257 @@
#! /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}
;;
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"
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
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
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"

303
build-32.sh Executable file
View File

@ -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

84
build-gcc.sh Executable file
View File

@ -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

234
build.sh Executable file
View File

@ -0,0 +1,234 @@
#! /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"
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
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
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"

72
cc.sh Executable file
View File

@ -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

417
check.sh Executable file
View File

@ -0,0 +1,417 @@
#! /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}-
;;
*)
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

40
compile.sh Executable file
View File

@ -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 || :

21
d Executable file
View File

@ -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

94
doit Executable file
View File

@ -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

54
elf.h
View File

@ -27,13 +27,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 +51,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,8 +77,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 +103,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 +121,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
@ -293,6 +306,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 +320,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. */
@ -399,6 +414,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 +424,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 +435,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 +529,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 +540,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 +551,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 +584,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 +596,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 +690,7 @@ typedef struct
} d_un;
} Elf32_Dyn;
#if HAVE_LONG_LONG
typedef struct
{
Elf64_Sxword d_tag; /* Dynamic entry type */
@ -674,6 +700,7 @@ typedef struct
Elf64_Addr d_ptr; /* Address value */
} d_un;
} Elf64_Dyn;
#endif
/* Legal values for d_tag (dynamic entry type). */
@ -843,6 +870,7 @@ typedef struct
entry */
} Elf32_Verdef;
#if HAVE_LONG_LONG
typedef struct
{
Elf64_Half vd_version; /* Version revision */
@ -854,7 +882,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 +908,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 +930,7 @@ typedef struct
entry */
} Elf32_Verneed;
#if HAVE_LONG_LONG
typedef struct
{
Elf64_Half vn_version; /* Version of structure */
@ -911,7 +941,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 +960,7 @@ typedef struct
entry */
} Elf32_Vernaux;
#if HAVE_LONG_LONG
typedef struct
{
Elf64_Word vna_hash; /* Hash value of dependency name */
@ -939,7 +970,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 +997,7 @@ typedef struct
} a_un;
} Elf32_auxv_t;
#if HAVE_LONG_LONG
typedef struct
{
uint64_t a_type; /* Entry type */
@ -977,6 +1009,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 +1078,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 +1139,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 +1159,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)
@ -1732,6 +1773,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 +1782,7 @@ typedef struct
Elf64_Word l_version; /* Interface version */
Elf64_Word l_flags; /* Flags */
} Elf64_Lib;
#endif
/* Legal values for l_flags. */

View File

@ -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)

View File

@ -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 */

View File

@ -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. */

View File

@ -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)

60
install.sh Executable file
View File

@ -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

View File

@ -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 */
@ -627,7 +629,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 +740,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 +784,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);

57
link.sh Executable file
View File

@ -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

34
tcc.h
View File

@ -390,12 +390,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 */
@ -410,6 +419,7 @@ typedef struct SValue {
} 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 +433,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 +615,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;
@ -1499,6 +1530,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 +1540,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);

View File

@ -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;
}

View File

@ -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

View File

@ -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)
{
@ -566,9 +591,13 @@ 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)) {
ei->r_offset > addr; i -= sizeof(*r)) {
ei = (ElfW_Rel*)(sr->data + i);
ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
*(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
*(ElfW_Rel*)(sr->data + i) = tmp;
@ -1147,6 +1176,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");
@ -1835,7 +1867,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)
@ -2167,7 +2199,9 @@ static int elf_output_file(TCCState *s1, const char *filename)
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 */

180
tccgen.c
View File

@ -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;
@ -1297,7 +1317,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 +1346,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;
@ -1649,16 +1673,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 +1716,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 +1762,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 +1900,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 +2324,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 +2347,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;
@ -2906,7 +2970,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 */
@ -4524,10 +4592,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++;
@ -4655,12 +4731,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 +4769,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;
@ -5332,6 +5426,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 +5438,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 +5556,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 +5887,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 +6063,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 +6197,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 +6315,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 +6365,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:

View File

@ -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 */

22
tccpp.c
View File

@ -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 */
@ -2282,7 +2291,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 +2364,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 +2403,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 +2438,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;
}

View File

@ -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
}

View File

@ -167,6 +167,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")

View File

@ -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"

143
test.sh Executable file
View File

@ -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

View File

@ -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 :*/

View File

@ -1,3 +0,0 @@
File 46_grep.c:
/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/