diff --git a/.gitignore b/.gitignore
index 3bff153f..d79c1c8a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,8 @@
 a.out
 tcc_g
 tcc
+tcc_c
+tcc_p
 *-tcc
 libtcc*.def
 
@@ -31,6 +33,7 @@ tcc.1
 *.pod
 tcc-doc.html
 tcc-doc.info
+tcc_c.tcov
 
 win32/doc
 win32/examples/libtcc_test.c
diff --git a/Makefile b/Makefile
index b52194ae..a117c8c1 100644
--- a/Makefile
+++ b/Makefile
@@ -68,7 +68,11 @@ endif
 TCCFLAGS-unx = -B$(TOP) -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP)
 TCCFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP) -L$(TOP)
 TCCFLAGS = $(TCCFLAGS$(CFG))
+ifdef USE_TCC_C
+TCC = $(TOP)/tcc_c$(EXESUF) $(TCCFLAGS)
+else
 TCC = $(TOP)/tcc$(EXESUF) $(TCCFLAGS)
+endif
 
 CFLAGS_P = $(CFLAGS) -pg -static -DCONFIG_TCC_STATIC -DTCC_PROFILE
 LIBS_P = $(LIBS)
@@ -459,8 +463,21 @@ tests2.%:
 testspp.%:
 	@$(MAKE) -C tests/pp $@
 
+# run all tests with code coverage
+tcc_c$(EXESUF): $($T_FILES)
+	@${TCC} -o $@ -ftest-coverage $< $(DEFINES) $(CFLAGS) $(LIBS) $(LDFLAGS)
+testc: tcc_c$(EXESUF)
+	@rm -f tcc_c.tcov
+	@USE_TCC_C=yes $(MAKE) -C tests
+testc2.%: tcc_c$(EXESUF)
+	@rm -f tcc_c.tcov
+	@USE_TCC_C=yes $(MAKE) -C tests/tests2 $@
+testcpp.%: tcc_c$(EXESUF)
+	@rm -f tcc_c.tcov
+	@USE_TCC_C=yes $(MAKE) -C tests/pp $@
+
 clean:
-	@rm -f tcc$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tags ETAGS *.pod
+	@rm -f tcc$(EXESUF) tcc_c$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tags ETAGS *.pod
 	@rm -f *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out *.dylib *_.h
 	@$(MAKE) -s -C lib $@
 	@$(MAKE) -s -C tests $@
@@ -489,12 +506,16 @@ help:
 	@echo "make test"
 	@echo "   run all tests"
 	@echo ""
-	@echo "make tests2.all / make tests2.37 / make tests2.37+"
-	@echo "   run all/single test(s) from tests2, optionally update .expect"
+	@echo "make tests2.all / make tests2.37 / make tests2.37+ / make tests2.37-"
+	@echo "   run all/single test(s) from tests2, optionally update .expect, display"
 	@echo ""
 	@echo "make testspp.all / make testspp.17"
 	@echo "   run all/single test(s) from tests/pp"
 	@echo ""
+	@echo "make testc / testc2.all / testc2.37 / testc2.37+ / testc2.37-"
+	@echo "make testcpp.all / make testcpp.17"
+	@echo "   run tests with code coverage. After test(s) see tcc_c.tcov"
+	@echo ""
 	@echo "Other supported make targets:"
 	@echo "   install install-strip doc clean tags ETAGS tar distclean help"
 	@echo ""
diff --git a/lib/tcov.c b/lib/tcov.c
index 32b7d18f..af09a734 100644
--- a/lib/tcov.c
+++ b/lib/tcov.c
@@ -340,9 +340,9 @@ void __store_test_coverage (unsigned char * p)
         for (i = 0; i < nfile->n_func; i++) {
 	    func = &nfile->func[i];
 	
-	    while (curline < func->first_line)
-		if (fgets(str, sizeof(str), src))
-		    fprintf (fp, "        -:%5u:%s", curline++, str);
+	    while (curline < func->first_line &&
+		   fgets(str, sizeof(str), src))
+		fprintf (fp, "        -:%5u:%s", curline++, str);
 	    blocks = 0;
 	    blocks_run = 0;
 	    for (j = 0; j < func->n_line; j++) {
@@ -390,9 +390,9 @@ void __store_test_coverage (unsigned char * p)
 		if (same_line)
 		     lline++;
 
-	        while (curline < fline)
-		    if (fgets(str, sizeof(str), src))
-		         fprintf (fp, "        -:%5u:%s", curline++, str);
+	        while (curline < fline &&
+		       fgets(str, sizeof(str), src))
+		     fprintf (fp, "        -:%5u:%s", curline++, str);
 		while (curline < lline &&
 		       fgets(str, sizeof(str), src)) {
 		    if (count == 0)
diff --git a/tcc.h b/tcc.h
index e104886f..ff75de14 100644
--- a/tcc.h
+++ b/tcc.h
@@ -399,6 +399,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
 
 #ifdef TCC_PROFILE /* profile all functions */
 # define static
+# define inline
 #endif
 
 /* -------------------------------------------- */
diff --git a/tests/pp/Makefile b/tests/pp/Makefile
index 224c866d..39441507 100644
--- a/tests/pp/Makefile
+++ b/tests/pp/Makefile
@@ -10,7 +10,7 @@ VPATH = $(SRC)
 files = $(patsubst %.$1,%.test,$(notdir $(wildcard $(SRC)/*.$1)))
 TESTS = $(call files,c) $(call files,S)
 
-all test testspp.all: $(sort $(TESTS))
+all test testspp.all testcpp.all: $(sort $(TESTS))
 
 DIFF_OPTS = -Nu -b
 
@@ -29,7 +29,7 @@ FILTER = 2>&1 | sed 's,$(SRC)/,,g'
 	    diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \
 	    && rm -f $*.output
 
-testspp.%: %.test ;
+testspp.% testcpp.%: %.test ;
 
 # automatically generate .expect files with gcc:
 %.expect: # %.c
diff --git a/tests/tests2/22_floating_point.c b/tests/tests2/22_floating_point.c
index 5dc7b746..d6d4028f 100644
--- a/tests/tests2/22_floating_point.c
+++ b/tests/tests2/22_floating_point.c
@@ -14,6 +14,14 @@ test()
    }
 }
 
+float f1 = 12.34f, f2 = 56.78f;
+double d1 = 12.34, d2 = 56.78;
+long double ld1 = 12.34l, ld2 = 56.78l;
+
+float tf = 12.34f + 56.78f - 12.34f * 56.78f + 12.34f / 56.78f;
+double td = 12.34 + 56.78 - 12.34 * 56.78 + 12.34 / 56.78;
+long double tld = 12.34l + 56.78l - 12.34l * 56.78l + 12.34l / 56.78l;
+
 int main()
 {
    static int e1 = -1.0 == 0.0;
@@ -23,45 +31,91 @@ int main()
    static int e5 = -1.0 <= 0.0;
    static int e6 = -1.0 > 0.0;
    // variables
-   float a = 12.34 + 56.78;
-   printf("%f\n", a);
+   float af = 12.34f + 56.78f;
+   double ad = 12.34 + 56.78;
+   long double ald = 12.34l + 56.78l;
+   printf("%f %f \n", af, tf);
+   printf("%g %g\n", ad, td);
+   printf("%Lf %Lf\n", ald, tld);
 
    // infix operators
-   printf("%f\n", 12.34 + 56.78);
-   printf("%f\n", 12.34 - 56.78);
-   printf("%f\n", 12.34 * 56.78);
-   printf("%f\n", 12.34 / 56.78);
+   printf("%f %f %f %f\n", 12.34f + 56.78f, 12.34f - 56.78f, 12.34f * 56.78f, 12.34f / 56.78f);
+   printf("%g %g %g %g\n", 12.34 + 56.78, 12.34 - 56.78, 12.34 * 56.78, 12.34 / 56.78);
+   printf("%Lf %Lf %Lf %Lf\n", 12.34l + 56.78l, 12.34l - 56.78l, 12.34l * 56.78l, 12.34l / 56.78l);
+#ifdef __i386__
+   // gcc/clang -m32 -mno-sse and tcc all fail for + and * but all have the same value
+   printf("%f %f %f %f\n", 12.34f + 56.78f, f1 - f2, 12.34f * 56.78f, f1 / f2);
+#else
+   printf("%f %f %f %f\n", f1 + f2, f1 - f2, f1 * f2, f1 / f2);
+#endif
+   printf("%g %g %g %g\n", d1 + d2, d1 - d2, d1 * d2, d1 / d2);
+   printf("%Lf %Lf %Lf %Lf\n", ld1 + ld2, ld1 - ld2, ld1 * ld2, ld1 / ld2);
 
    // comparison operators
+   printf("%d %d %d %d %d %d\n", 12.34f < 56.78f, 12.34f <= 56.78f, 12.34f == 56.78f, 12.34f >= 56.78f, 12.34f > 56.78f, 12.34f != 56.78f);
+   printf("%d %d %d %d %d %d\n", 12.34f < 12.34f, 12.34f <= 12.34f, 12.34f == 12.34f, 12.34f >= 12.34f, 12.34f > 12.34f, 12.34f != 12.34f);
+   printf("%d %d %d %d %d %d\n", 56.78f < 12.34f, 56.78f <= 12.34f, 56.78f == 12.34f, 56.78f >= 12.34f, 56.78f > 12.34f, 56.78f != 12.34f);
    printf("%d %d %d %d %d %d\n", 12.34 < 56.78, 12.34 <= 56.78, 12.34 == 56.78, 12.34 >= 56.78, 12.34 > 56.78, 12.34 != 56.78);
    printf("%d %d %d %d %d %d\n", 12.34 < 12.34, 12.34 <= 12.34, 12.34 == 12.34, 12.34 >= 12.34, 12.34 > 12.34, 12.34 != 12.34);
    printf("%d %d %d %d %d %d\n", 56.78 < 12.34, 56.78 <= 12.34, 56.78 == 12.34, 56.78 >= 12.34, 56.78 > 12.34, 56.78 != 12.34);
+   printf("%d %d %d %d %d %d\n", 12.34l < 56.78l, 12.34l <= 56.78l, 12.34l == 56.78l, 12.34l >= 56.78l, 12.34l > 56.78l, 12.34l != 56.78l);
+   printf("%d %d %d %d %d %d\n", 12.34l < 12.34l, 12.34l <= 12.34l, 12.34l == 12.34l, 12.34l >= 12.34l, 12.34l > 12.34l, 12.34l != 12.34l);
+   printf("%d %d %d %d %d %d\n", 56.78l < 12.34l, 56.78l <= 12.34l, 56.78l == 12.34l, 56.78l >= 12.34l, 56.78l > 12.34l, 56.78l != 12.34l);
+   printf("%d %d %d %d %d %d\n", f1 < f2, f1 <= f2, f1 == f2, f1 >= f2, f1 > f2, f1 != f2);
+   printf("%d %d %d %d %d %d\n", f1 < f1, f1 <= f1, f1 == f1, f1 >= f1, f1 > f1, f1 != f1);
+   printf("%d %d %d %d %d %d\n", f2 < f1, f2 <= f1, f2 == f1, f2 >= f1, f2 > f1, f2 != f1);
+   printf("%d %d %d %d %d %d\n", d1 < d2, d1 <= d2, d1 == d2, d1 >= d2, d1 > d2, d1 != d2);
+   printf("%d %d %d %d %d %d\n", d1 < d1, d1 <= d1, d1 == d1, d1 >= d1, d1 > d1, d1 != d1);
+   printf("%d %d %d %d %d %d\n", d2 < d1, d2 <= d1, d2 == d1, d2 >= d1, d2 > d1, d2 != d1);
+   printf("%d %d %d %d %d %d\n", ld1 < ld2, ld1 <= ld2, ld1 == ld2, ld1 >= ld2, ld1 > ld2, ld1 != ld2);
+   printf("%d %d %d %d %d %d\n", ld1 < ld1, ld1 <= ld1, ld1 == ld1, ld1 >= ld1, ld1 > ld1, ld1 != ld1);
+   printf("%d %d %d %d %d %d\n", ld2 < ld1, ld2 <= ld1, ld2 == ld1, ld2 >= ld1, ld2 > ld1, ld2 != ld1);
    printf("%d %d %d %d %d %d\n", e1, e2, e3, e4, e5, e6);
 
    // assignment operators
-   a = 12.34;
-   a += 56.78;
-   printf("%f\n", a);
+   af = 12.34f; ad = 12.34; ald = 12.34l;
+   af += 56.78f; ad += 56.78; ald += 56.78l;
+   printf("%f %g %Lf\n", af, ad, ald);
+#ifdef __i386__
+   printf("%f %g %Lf\n", af, ad, ald);
+#else
+   af = f1; ad = d1; ald = ld1;
+   af += f2; ad += d2; ald += ld2;
+   printf("%f %g %Lf\n", af, ad, ald);
+#endif
 
-   a = 12.34;
-   a -= 56.78;
-   printf("%f\n", a);
+   af = 12.34f; ad = 12.34; ald = 12.34l;
+   af -= 56.78f; ad -= 56.78; ald -= 56.78l;
+   printf("%f %g %Lf\n", af, ad, ald);
+   af = f1; ad = d1; ald = ld1;
+   af -= f2; ad -= d2; ald -= ld2;
+   printf("%f %g %Lf\n", af, ad, ald);
 
-   a = 12.34;
-   a *= 56.78;
-   printf("%f\n", a);
+   af = 12.34f; ad = 12.34; ald = 12.34l;
+   af *= 56.78f; ad *= 56.78; ald *= 56.78l;
+   printf("%f %g %Lf\n", af, ad, ald);
+#ifdef __i386__
+   printf("%f %g %Lf\n", af, ad, ald);
+#else
+   af = f1; ad = d1; ald = ld1;
+   af *= f2; ad *= d2; ald *= ld2;
+   printf("%f %g %Lf\n", af, ad, ald);
+#endif
 
-   a = 12.34;
-   a /= 56.78;
-   printf("%f\n", a);
+   af = 12.34f; ad = 12.34; ald = 12.34l;
+   af /= 56.78f; ad /= 56.78; ald /= 56.78l;
+   printf("%f %g %Lf\n", af, ad, ald);
+   af = f1; ad = d1; ald = ld1;
+   af /= f2; ad /= d2; ald /= ld2;
+   printf("%f %g %Lf\n", af, ad, ald);
 
    // prefix operators
-   printf("%f\n", +12.34);
-   printf("%f\n", -12.34);
+   printf("%f %g %Lf\n", +12.34f, +12.34, +12.34l);
+   printf("%f %g %Lf\n", -12.34f, -12.34, -12.34l);
 
    // type coercion
-   a = 2;
-   printf("%f\n", a);
+   af = 2;
+   printf("%f\n", af);
    printf("%f\n", sin(2));
 
    return 0;
diff --git a/tests/tests2/22_floating_point.expect b/tests/tests2/22_floating_point.expect
index a989eca1..d9c803e0 100644
--- a/tests/tests2/22_floating_point.expect
+++ b/tests/tests2/22_floating_point.expect
@@ -1,17 +1,40 @@
-69.120003
-69.120000
--44.440000
-700.665200
-0.217330
+69.119995 -631.327881 
+69.12 -631.328
+69.120000 -631.327870
+69.119995 -44.439999 700.665222 0.217330
+69.12 -44.44 700.665 0.21733
+69.120000 -44.440000 700.665200 0.217330
+69.119995 -44.439999 700.665222 0.217330
+69.12 -44.44 700.665 0.21733
+69.120000 -44.440000 700.665200 0.217330
+1 1 0 0 0 1
+0 1 1 1 0 0
+0 0 0 1 1 1
+1 1 0 0 0 1
+0 1 1 1 0 0
+0 0 0 1 1 1
+1 1 0 0 0 1
+0 1 1 1 0 0
+0 0 0 1 1 1
+1 1 0 0 0 1
+0 1 1 1 0 0
+0 0 0 1 1 1
+1 1 0 0 0 1
+0 1 1 1 0 0
+0 0 0 1 1 1
 1 1 0 0 0 1
 0 1 1 1 0 0
 0 0 0 1 1 1
 0 1 1 0 1 0
-69.120003
--44.439999
-700.665222
-0.217330
-12.340000
--12.340000
+69.119995 69.12 69.120000
+69.119995 69.12 69.120000
+-44.439999 -44.44 -44.440000
+-44.439999 -44.44 -44.440000
+700.665222 700.665 700.665200
+700.665222 700.665 700.665200
+0.217330 0.21733 0.217330
+0.217330 0.21733 0.217330
+12.340000 12.34 12.340000
+-12.340000 -12.34 -12.340000
 2.000000
 0.909297
diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile
index ebb271ab..1d8ed72a 100644
--- a/tests/tests2/Makefile
+++ b/tests/tests2/Makefile
@@ -124,7 +124,7 @@ endif
 # Filter source directory in warnings/errors (out-of-tree builds)
 FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'
 
-all test tests2.all: $(filter-out $(SKIP),$(TESTS))
+all test tests2.all testc2.all: $(filter-out $(SKIP),$(TESTS))
 	@$(MAKE) clean --no-print-directory -s
 
 %.test: %.c %.expect
@@ -138,15 +138,15 @@ T3 = $(FILTER) >$*.output 2>&1 || true \
      && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS))
 
 # run single test and update .expect file, e.g. "make tests2.37+"
-tests2.%+:
+tests2.%+ testc2.%+:
 	@$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory
 
 # just run tcc to see the output, e.g. "make tests2.37-"
-tests2.%-:
+tests2.%- testc2.%-:
 	@$(MAKE) $(call F1,$*) T3= --no-print-directory
 
 # run single test, e.g. "make tests2.37"
-tests2.%:
+tests2.% testc2.%:
 	@$(MAKE) $(call F1,$*) --no-print-directory
 
 F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test)