tinycc/lib
Balazs Kezes 49d3118621 Incorrect function call code on ARMv6
On 2016-08-11 09:24 +0100, Balazs Kezes wrote:
> I think it's just that that copy_params() never restores the spilled
> registers. Maybe it needs some extra code at the end to see if any
> parameters have been spilled to stack and then restore them?

I've spent some time on this and I've found an alternative solution.
Although I'm not entirely sure about it but I've attached a patch
nevertheless.

And while poking at that I've found another problem affecting the
unsigned long long division on arm and I've attached a patch for that
too.

More details in the patches themselves. Please review and consider them
for merging! Thank you!

--
Balazs

[PATCH 1/2] Fix slow unsigned long long division on ARM

The macro AEABI_UXDIVMOD expands to this bit:

  #define AEABI_UXDIVMOD(name,type, rettype, typemacro)                     \
  ...
      while (num >= den) {                                                  \
  ...
          while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
              q <<= 1;                                                      \
  ...

With the current ULONG_MAX version the inner loop goes only until 4
billion so the outer loop will progress very slowly if num is large.
With ULLONG_MAX the inner loop works as expected. The current version is
probably a result of a typo.

The following bash snippet demonstrates the bug:

  $ uname -a
  Linux eper 4.4.16-2-ARCH #1 Wed Aug 10 20:03:13 MDT 2016 armv6l GNU/Linux
  $ cat div.c
  int printf(const char *, ...);
  int main(void) {
    unsigned long long num, denom;
    num = 12345678901234567ULL;
    denom = 7;
    printf("%lld\n", num / denom);
    return 0;
  }
  $ time tcc -run div.c
  1763668414462081

  real    0m16.291s
  user    0m15.860s
  sys     0m0.020s

[PATCH 2/2] Fix long long dereference during argument passing on ARMv6

For some reason the code spills the register to the stack. copy_params
in arm-gen.c doesn't expect this so bad code is generated. It's not
entirely clear why the saving part is necessary. It was added in commit
59c35638 with the comment "fixed long long code gen bug" with no further
clarification. Given that tcctest.c passes without this, maybe it's no
longer needed? Let's remove it.

Also add a new testcase just for this. After I've managed to make the
tests compile on a raspberry pi, I get the following diff without this
patch:

  --- test.ref    2016-08-22 22:12:43.380000000 +0100
  +++ test.out3   2016-08-22 22:12:49.990000000 +0100
  @@ -499,7 +499,7 @@
   2
   1 0 1 0
   4886718345
  -shift: 9 9 9312
  +shift: 291 291 291
   shiftc: 36 36 2328
   shiftc: 0 0 9998683865088
   manyarg_test:

More discussion on this thread:
https://lists.nongnu.org/archive/html/tinycc-devel/2016-08/msg00004.html
2016-10-01 23:10:11 +02:00
..
Makefile build: restore out-of-tree support 2016-10-01 21:06:53 +02:00
alloca-arm.S arm: Provide alloca() 2014-04-05 22:54:11 +02:00
alloca86-bt.S Fix mistake. Change jb by jbe. tiny c round (INT_MAX = 0x7FFFFFFF) to a DWORD boundary and it becomes 0x80000000. Jle treats as -214783648, but Jbe treats as 214783648. Thanks to Jason Hood for explain me this. 2014-07-10 20:41:51 -04:00
alloca86.S Fix mistake. Change jb by jbe. tiny c round (INT_MAX = 0x7FFFFFFF) to a DWORD boundary and it becomes 0x80000000. Jle treats as -214783648, but Jbe treats as 214783648. Thanks to Jason Hood for explain me this. 2014-07-10 20:41:51 -04:00
alloca86_64-bt.S Revert part of "fix installation amd bcheck for Windows" 2016-10-01 20:47:36 +02:00
alloca86_64.S Fix mistake. Change jb by jbe. tiny c round (INT_MAX = 0x7FFFFFFF) to a DWORD boundary and it becomes 0x80000000. Jle treats as -214783648, but Jbe treats as 214783648. Thanks to Jason Hood for explain me this. 2014-07-10 20:41:51 -04:00
armeabi.c Incorrect function call code on ARMv6 2016-10-01 23:10:11 +02:00
bcheck.c Revert part of "fix installation amd bcheck for Windows" 2016-10-01 20:47:36 +02:00
lib-arm64.c Correct prototype: void __clear_cache(void *, void *). 2015-10-15 19:02:54 +01:00
libtcc1.c lib/libtcc1.c: Replace "long" with "unsigned int" in union float_long. 2015-11-04 23:22:00 +00:00