Add Intel MCU target

Intel MCU System V ABI are incompartible with i386 System V ABI:
    o Minimum instruction set is Intel Pentium ISA minus x87 instructions
    o No x87 or vector registers
    o First three args are passed in %eax, %edx and %ecx
    o Full specification available here:
      https://github.com/hjl-tools/x86-psABI/wiki/iamcu-psABI-0.7.pdf

newlib/
    * configure.host: Add new ix86-*-elfiamcu target

newlib/libc/include/
    * setjmp.h: Change _JBLEN for Intel MCU target

newlib/libc/machine/i386/
    * memchr.S:  (memchr)  Target-specific size-optimized version
    * memcmp.S:  (memcmp)  Likewise
    * memcpy.S:  (memcpy)  Likewise
    * memmove.S: (memmove) Likewise
    * memset.S:  (memset)  Likewise
    * setjmp.S:  (setjmp)  Likewise
    * strchr.S:  (strchr)  Likewise
    * strlen.S:  (strlen)  Likewise

newlib/libc/stdlib/
    * srtold.c:  (__flt_rounds) Disable for Intel MCU
This commit is contained in:
Igor Venevtsev 2016-03-31 12:12:00 +03:00 committed by Corinna Vinschen
parent 44b72b43d6
commit 5d3ad3b123
11 changed files with 184 additions and 3 deletions

View File

@ -696,6 +696,15 @@ case "${host}" in
i[34567]86-*-netware*)
newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES -DNO_EXEC -DABORT_PROVIDED -DCLOCK_PROVIDED -DMALLOC_PROVIDED -DHAVE_FCNTL"
;;
i[3-7]86-*-elfiamcu)
newlib_cflags="${newlib_cflags} -Os -DPREFER_SIZE_OVER_SPEED -ffunction-sections -fomit-frame-pointer -DREENTRANT_SYSCALL_PROVIDED"
if [ "${newlib_multithread}" = "no" ] ; then
newlib_cflags="${newlib_cflags} -DMISSING_SYSCALL_NAMES"
else
syscall_dir=syscalls
newlib_cflags="${newlib_cflags} -D__DYNAMIC_REENT__"
fi
;;
iq2000*)
syscall_dir=syscalls
default_newlib_io_long_long="yes"

View File

@ -92,6 +92,9 @@ _BEGIN_STD_C
# define _JBLEN (13 * 4)
# elif defined(__unix__) || defined(__rtems__)
# define _JBLEN 9
# elif defined(__iamcu__)
/* Intel MCU jmp_buf only covers callee-saved registers. */
# define _JBLEN 6
# else
# include "setjmp-dj.h"
# endif

View File

@ -14,13 +14,33 @@
SOTYPE_FUNCTION(memchr)
SYM (memchr):
#ifdef __iamcu__
pushl edi
movl eax,edi
movl edx,eax
xorl edx,edx
testl ecx,ecx
jz L20
repnz
scasb
setnz dl
decl edi
decl edx
andl edi,edx
L20:
movl edx,eax
popl edi
#else
pushl ebp
movl esp,ebp
pushl edi
movzbl 12(ebp),eax
movl 16(ebp),ecx
movl 8(ebp),edi
xorl edx,edx
testl ecx,ecx
jz L20
@ -111,4 +131,5 @@ L20:
leal -4(ebp),esp
popl edi
leave
#endif
ret

View File

@ -15,6 +15,33 @@
SYM (memcmp):
#ifdef __iamcu__
pushl edi
pushl esi
movl eax,edi
movl edx,esi
cld
/* check if length is zero in which case just return 0 */
xorl eax,eax
testl ecx,ecx
jz L4
/* compare any unaligned bytes or remainder bytes */
repz
cmpsb
/* set output to be < 0 if less than, 0 if equal, or > 0 if greater than */
xorl edx,edx
movb -1(esi),dl
movb -1(edi),al
subl edx,eax
L4:
popl esi
popl edi
#else
pushl ebp
movl esp,ebp
subl $16,esp
@ -73,4 +100,5 @@ L4:
popl edi
popl ebx
leave
#endif
ret

View File

@ -15,6 +15,17 @@
SYM (memcpy):
#ifdef __iamcu__
pushl esi
pushl edi
movl eax,edi
movl edx,esi
rep movsb
popl edi
popl esi
#else
pushl ebp
movl esp,ebp
pushl esi
@ -71,4 +82,5 @@ SYM (memcpy):
popl edi
popl esi
leave
#endif
ret

View File

@ -15,6 +15,32 @@
SYM (memmove):
#ifdef __iamcu__
pushl esi
pushl edi
movl eax,edi
movl edx,esi
cmp esi,edi
ja .Lcopy_backward
je .Lbwd_write_0bytes
rep movsb
popl edi
popl esi
ret
.Lcopy_backward:
lea -1(edi,ecx),edi
lea -1(esi,ecx),esi
std
rep movsb
cld
.Lbwd_write_0bytes:
popl edi
popl esi
#else
pushl ebp
movl esp,ebp
pushl esi
@ -143,4 +169,5 @@ SYM (memmove):
popl edi
popl esi
leave
#endif
ret

View File

@ -15,6 +15,15 @@
SYM (memset):
#ifdef __iamcu__
pushl edi
movl eax,edi
movzbl dl,eax
mov edi,edx
rep stosb
mov edx,eax
popl edi
#else
pushl ebp
movl esp,ebp
pushl edi
@ -96,4 +105,5 @@ SYM (memset):
leal -4(ebp),esp
popl edi
leave
#endif
ret

View File

@ -20,6 +20,10 @@
** jmp_buf:
** eax ebx ecx edx esi edi ebp esp eip
** 0 4 8 12 16 20 24 28 32
**
** Intel MCU jmp_buf:
** ebx esi edi ebp esp eip
** 0 4 8 12 16 20
*/
#include "i386mach.h"
@ -31,6 +35,23 @@
SYM (setjmp):
#ifdef __iamcu__
/* Store EIP. */
movl 0(esp),ecx
movl ecx,20(eax)
movl ebx,0 (eax)
movl esi,4 (eax)
movl edi,8 (eax)
movl ebp,12(eax)
/* Skip return address, which will be pushed onto stack in
longjmp, and store SP. */
leal 4(esp),ecx
movl ecx,16(eax)
xorl eax,eax
#else
pushl ebp
movl esp,ebp
@ -59,9 +80,28 @@ SYM (setjmp):
popl edi
movl $0,eax
leave
#endif
ret
SYM (longjmp):
#ifdef __iamcu__
/* Check retval. */
testl edx,edx
jne 0f
incl edx
0:
/* Restore stack first. */
movl 16(eax),esp
/* Put return address on stack. */
pushl 20(eax)
movl 0(eax),ebx
movl 4(eax),esi
movl 8(eax),edi
movl 12(eax),ebp
movl edx,eax
#else
pushl ebp
movl esp,ebp
@ -87,5 +127,6 @@ SYM (longjmp):
movl 16(edi),esi
movl 20(edi),edi
__STI
#endif
ret

View File

@ -15,6 +15,29 @@
SYM (strchr):
#ifdef __iamcu__
xorl ecx,ecx
movb dl,cl
/* loop while (*s && *s++ != c) */
leal -1(eax),eax
L15:
incl eax
movb (eax),dl
testb dl,dl
je L14
cmpb cl,dl
jne L15
L14:
/* if (*s == c) return address otherwise return NULL */
cmpb cl,(eax)
je L19
xorl eax,eax
L19:
ret
#else
pushl ebp
movl esp,ebp
pushl edi
@ -170,3 +193,5 @@ L27:
jmp L9
#endif /* !__OPTIMIZE_SIZE__ */
#endif /* __iamcu__ */

View File

@ -18,9 +18,13 @@ SYM (strlen):
pushl ebp
movl esp,ebp
pushl edi
#ifdef __iamcu__
movl eax,edx
#else
movl 8(ebp),edx
#endif
#ifdef __OPTIMIZE_SIZE__
#if defined __OPTIMIZE_SIZE__ || defined __iamcu__
cld
movl edx,edi
movl $4294967295,ecx

View File

@ -35,7 +35,8 @@ POSSIBILITY OF SUCH DAMAGE.
#ifdef _HAVE_LONG_DOUBLE
#if defined (__x86_64__) || defined (__i386__)
/* Intel MCU has no x87 floating point unit */
#if (defined (__x86_64__) || defined (__i386__)) && !defined (__iamcu__)
static const int map[] = {
1, /* round to nearest */
3, /* round to zero */