From 5d3ad3b123b7c121d7a6eac27fb13016171e27bc Mon Sep 17 00:00:00 2001 From: Igor Venevtsev Date: Thu, 31 Mar 2016 12:12:00 +0300 Subject: 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 diff --git a/newlib/configure.host b/newlib/configure.host index 8b0846e..bb163ec 100644 --- a/newlib/configure.host +++ b/newlib/configure.host @@ -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" diff --git a/newlib/libc/include/machine/setjmp.h b/newlib/libc/include/machine/setjmp.h index c08e682..2b4dd8b 100644 --- a/newlib/libc/include/machine/setjmp.h +++ b/newlib/libc/include/machine/setjmp.h @@ -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 diff --git a/newlib/libc/machine/i386/memchr.S b/newlib/libc/machine/i386/memchr.S index 7639685..d9b0bf2 100644 --- a/newlib/libc/machine/i386/memchr.S +++ b/newlib/libc/machine/i386/memchr.S @@ -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 diff --git a/newlib/libc/machine/i386/memcmp.S b/newlib/libc/machine/i386/memcmp.S index 26b8ef1..4a01b82 100644 --- a/newlib/libc/machine/i386/memcmp.S +++ b/newlib/libc/machine/i386/memcmp.S @@ -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 diff --git a/newlib/libc/machine/i386/memcpy.S b/newlib/libc/machine/i386/memcpy.S index b53e2a1..a14aa2a 100644 --- a/newlib/libc/machine/i386/memcpy.S +++ b/newlib/libc/machine/i386/memcpy.S @@ -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 diff --git a/newlib/libc/machine/i386/memmove.S b/newlib/libc/machine/i386/memmove.S index 1ea2f6d..1026582 100644 --- a/newlib/libc/machine/i386/memmove.S +++ b/newlib/libc/machine/i386/memmove.S @@ -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 diff --git a/newlib/libc/machine/i386/memset.S b/newlib/libc/machine/i386/memset.S index 6eb2cd6..83b2556 100644 --- a/newlib/libc/machine/i386/memset.S +++ b/newlib/libc/machine/i386/memset.S @@ -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 diff --git a/newlib/libc/machine/i386/setjmp.S b/newlib/libc/machine/i386/setjmp.S index fd746e4..45c689f 100644 --- a/newlib/libc/machine/i386/setjmp.S +++ b/newlib/libc/machine/i386/setjmp.S @@ -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 diff --git a/newlib/libc/machine/i386/strchr.S b/newlib/libc/machine/i386/strchr.S index 1d98b81..43ee0fb 100644 --- a/newlib/libc/machine/i386/strchr.S +++ b/newlib/libc/machine/i386/strchr.S @@ -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__ */ diff --git a/newlib/libc/machine/i386/strlen.S b/newlib/libc/machine/i386/strlen.S index 0e3cb64..373ea0f 100644 --- a/newlib/libc/machine/i386/strlen.S +++ b/newlib/libc/machine/i386/strlen.S @@ -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 diff --git a/newlib/libc/stdlib/strtold.c b/newlib/libc/stdlib/strtold.c index a6d415d..1128b74 100644 --- a/newlib/libc/stdlib/strtold.c +++ b/newlib/libc/stdlib/strtold.c @@ -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 */