diff options
author | Igor Venevtsev <igor.venevtsev@gmail.com> | 2016-03-31 12:12:00 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2016-04-04 16:32:07 +0200 |
commit | 5d3ad3b123b7c121d7a6eac27fb13016171e27bc (patch) | |
tree | 1addf58b9430f0d224f6775dc90dd36b6d1e62b8 /newlib/libc | |
parent | 44b72b43d6e867408a1ce6bc7df6d60a5c968183 (diff) | |
download | newlib-5d3ad3b123b7c121d7a6eac27fb13016171e27bc.zip newlib-5d3ad3b123b7c121d7a6eac27fb13016171e27bc.tar.gz newlib-5d3ad3b123b7c121d7a6eac27fb13016171e27bc.tar.bz2 |
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
Diffstat (limited to 'newlib/libc')
-rw-r--r-- | newlib/libc/include/machine/setjmp.h | 3 | ||||
-rw-r--r-- | newlib/libc/machine/i386/memchr.S | 23 | ||||
-rw-r--r-- | newlib/libc/machine/i386/memcmp.S | 28 | ||||
-rw-r--r-- | newlib/libc/machine/i386/memcpy.S | 12 | ||||
-rw-r--r-- | newlib/libc/machine/i386/memmove.S | 27 | ||||
-rw-r--r-- | newlib/libc/machine/i386/memset.S | 10 | ||||
-rw-r--r-- | newlib/libc/machine/i386/setjmp.S | 41 | ||||
-rw-r--r-- | newlib/libc/machine/i386/strchr.S | 25 | ||||
-rw-r--r-- | newlib/libc/machine/i386/strlen.S | 6 | ||||
-rw-r--r-- | newlib/libc/stdlib/strtold.c | 3 |
10 files changed, 175 insertions, 3 deletions
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 */ |