avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] PATCH: fix ctype linker errors


From: Stefano Fedrigo
Subject: Re: [avr-libc-dev] PATCH: fix ctype linker errors
Date: Mon, 04 Apr 2005 18:42:26 +0200
User-agent: Mozilla Thunderbird 1.0.2 (X11/20050324)

Dmitry K. wrote:
>>ctype.S contains several functions that end up in different sections.
>>All them branch to __cty_isfalse and __cty_istrue, which resides in yet
>>another section. Thus there is no guarantee that all sections are
>>allocated next to each other within the limit of relative branch
>>instructions.
> 
> ...
> 
>>The best fix I could come up with consists in copying the
>>three-instruction sequence into each section. Is there a better solution?
> 
> There is, for example:
> 
>           TEXT_SEG(ctype, isdigit)
>           FUNCTION(isdigit)
> GLOBAL(isdigit)
>           TST   rHigh
>           BRNE  __ctype_isfalse
>           CPI   rLow,'0'
>           BRLT  __ctype_isfalse
>           CPI   rLow,'9'+1
>           BRGE  __ctype_isfalse
>           RET                      ; '0' <= rLow <= '9' (!= 0!!)
> in to:
>         ...
>           cpse  rHigh, r1
>   1:      rjmp  __ctype_isfalse
>           CPI   rLow,'0'
>           BRLT  1b
>           CPI   rLow,'9'+1
>           BRGE  1b
>           RET                      ; '0' <= rLow <= '9' (!= 0!!)

I didn't see that all the code in the file resides in the same section
(.progmem.ctype). However the range of branch instructions is only 128
words. I improved my patch keeping the __ctype_is_false section and
using RJMP to jump to it (4 Kwords range), without duplication of the
__ctype_is_false code in each function.

I tested the new code with an atmega128. The patch is attached.

Which value should the function iscntrl() return for input between 128
and 255? Currently returns true: is this correct?

GLOBAL(iscntrl)
          TST   rHigh
          BRNE  __ctype_isfalse
          CPI   rLow,0x7F
          BREQ  __ctype_istrue
          CPI   rLow,0x1F+1
          BRGE  __ctype_isfalse
          SER   rLow               ; 0 is cntrl, too! -> return true
          RET

If not, the last BRGE should be a BRSH.

Can I submit this patch on Savannah?

-- 
  // Stefano Fedrigo - Develer S.r.l., R&D dept.
\X/  http://www.develer.com
diff -Nru avr-libc-1.2.2.orig/libc/stdlib/ctype.S 
avr-libc-1.2.2/libc/stdlib/ctype.S
--- avr-libc-1.2.2.orig/libc/stdlib/ctype.S     2005-03-24 22:25:38.000000000 
+0100
+++ avr-libc-1.2.2/libc/stdlib/ctype.S  2005-03-29 19:48:37.000000000 +0200
@@ -75,8 +75,8 @@
           FUNCTION(isascii)
 
 GLOBAL(isascii)
-          TST     rHigh
-          BRNE    __ctype_isfalse
+          CPSE    rHigh,__zero_reg__
+          RJMP    _U(__ctype_isfalse)
           COM     rLow
           ANDI    rLow, 0x80
           RET
@@ -101,13 +101,15 @@
           FUNCTION(isalnum)
 
 GLOBAL(isalnum)
-          TST   rHigh
-          BRNE  __ctype_isfalse
+          CPSE  rHigh,__zero_reg__
+          RJMP  _U(__ctype_isfalse)
           PUSH  rLow               ; save, destroyed by isdigit returning 0
           RCALL _U(isdigit)
           TST   rLow
           POP   rLow
-          BRNE  __ctype_istrue
+          BREQ  1f
+          RET                      ; true
+1:
           RJMP  _U(isalpha)
 
           ENDFUNC
@@ -133,19 +135,20 @@
           FUNCTION(isupper)
 
 GLOBAL(isupper)
-          ;TST   rHigh
-          ;BRNE  __ctype_isfalse    ; checked by _islower later on
+          ;CPSE  rHigh,__zero_reg__
+          ;RJMP  _U(__ctype_isfalse)    ; checked by _islower later on
           SBRC  rLow,5       ; if bit 5 is set it is no upper
-          RJMP  __ctype_isfalse     ; bit 5 is clear, so if isalpha is true it 
is an upper
+          RJMP  _U(__ctype_isfalse)     ; bit 5 is clear, so if isalpha is 
true it is an upper
 GLOBAL(isalpha)
           ORI     rLow,0x20        ; make a lower out of an upper (all others 
are changed but do not get alpha)
 GLOBAL(islower)
-          TST   rHigh
-          BRNE  __ctype_isfalse
+          CPSE  rHigh,__zero_reg__
+1:
+          RJMP  _U(__ctype_isfalse)
           CPI   rLow,'a'
-          BRLT  __ctype_isfalse
+          BRLT  1b
           CPI   rLow,'z'+1
-          BRGE  __ctype_isfalse
+          BRGE  1b
           RET                      ; 'a' <= rLow <= 'z' (!= 0!!, Z=0)
 
           ENDFUNC
@@ -158,13 +161,13 @@
           FUNCTION(isdigit)
 
 GLOBAL(isdigit)
-          TST   rHigh
-          BRNE  __ctype_isfalse
-          CPI   rLow,'0'
-          BRLT  __ctype_isfalse
-          CPI   rLow,'9'+1
-          BRGE  __ctype_isfalse
-          RET                      ; '0' <= rLow <= '9' (!= 0!!)
+          CPSE  rHigh,__zero_reg__
+1:        
+          RJMP  _U(__ctype_isfalse)
+          SUBI  rLow,'0'
+          SUBI  rLow,10
+          BRSH  1b
+          RET                      ; rLow: -10..-1
 
           ENDFUNC
 #endif
@@ -181,8 +184,10 @@
           CPI   rLow,'a'
           BRLT  _isxdigit00
           CPI   rLow,'f'+1
-          BRGE  __ctype_isfalse
+          BRGE  1f
           RET                      ; 'a' <= rLow <= 'f' (!= 0!!)
+1:
+          RJMP  _U(__ctype_isfalse)
 _isxdigit00:
           MOV   rLow,__tmp_reg__
           RJMP  _U(isdigit)
@@ -197,13 +202,15 @@
           FUNCTION(iscntrl)
 
 GLOBAL(iscntrl)
-          TST   rHigh
-          BRNE  __ctype_isfalse
+          CPSE  rHigh,__zero_reg__
+1:
+          RJMP  _U(__ctype_isfalse)
           CPI   rLow,0x7F
-          BREQ  __ctype_istrue
+          BREQ  2f
           CPI   rLow,0x1F+1
-          BRGE  __ctype_isfalse
+          BRGE  1b
           SER   rLow               ; 0 is cntrl, too! -> return true
+2:
           RET
 
           ENDFUNC
@@ -217,15 +224,17 @@
 
 GLOBAL(isgraph)
           CPI   rLow,' '
-          BREQ  __ctype_isfalse
+          BREQ  1f
 GLOBAL(isprint)
           TST   rHigh
-          BRNE  __ctype_isfalse
+          BRNE  1f
           CPI   rLow,' '
-          BRLT  __ctype_isfalse
+          BRLT  1f
           CPI   rLow,0x7E+1
-          BRGE  __ctype_isfalse    ;  ' ' <= rLow <= 0x7E (!= 0!!)
+          BRGE  1f                 ;  ' ' <= rLow <= 0x7E (!= 0!!)
           RET
+1:
+          RJMP  _U(__ctype_isfalse)
 
           ENDFUNC
 #endif
@@ -237,20 +246,22 @@
           FUNCTION(isspace)
 
 GLOBAL(isspace)
-          TST   rHigh
-          BRNE  __ctype_isfalse
+          CPSE  rHigh,__zero_reg__
+1:
+          RJMP  _U(__ctype_isfalse)
           CPI   rLow,' '           ; blank
-          BREQ  __ctype_istrue
+          BREQ  2f
           CPI   rLow,0x0A    ;'\n' ; line feed
-          BREQ  __ctype_istrue
+          BREQ  2f
           CPI   rLow,0x0C    ;'\f' ; form feed
-          BREQ  __ctype_istrue
+          BREQ  2f
           CPI   rLow,0x0D    ;'\r' ; carriage return
-          BREQ  __ctype_istrue
+          BREQ  2f
           CPI   rLow,0x09    ;'\t' ; tab
-          BREQ  __ctype_istrue
+          BREQ  2f
           CPI   rLow,0x0B    ;'\v' ; vertical tab
-          BRNE  __ctype_isfalse
+          BRNE  1b
+2:
           RET
 
           ENDFUNC
@@ -268,12 +279,13 @@
           BREQ  _ispunct00           ; true : CPI rLow,0x7E+1 -> NE, rLow 
unchanged
 
           RCALL _U(isspace)
-          TST   rLow
-          BRNE  __ctype_isfalse
+          CPSE  rLow,__zero_reg__
+1:
+          RJMP  _U(__ctype_isfalse)
           mov   rLow, __tmp_reg__    ; **changed**
           RCALL _U(isalnum)
           TST   rLow
-          BRNE  __ctype_isfalse
+          BRNE  1b
           SER   rLow
 _ispunct00:
           RET
@@ -288,14 +300,16 @@
           FUNCTION(isblank)
 
 GLOBAL(isblank)
-          TST   rHigh
-          BRNE  __ctype_isfalse
+          CPSE  rHigh,__zero_reg__
+1:
+          RJMP  _U(__ctype_isfalse)
           CPI   rLow,' '           ; blank
-          BREQ  __ctype_istrue
+          BREQ  2f
           CPI   rLow,0x09    ;'\t' ; tab
-          BREQ  __ctype_istrue
+          BREQ  2f
           CPI   rLow,0x0B    ;'\v' ; vertical tab
-          BRNE  __ctype_isfalse
+          BRNE  1b
+2:
           RET
 
           ENDFUNC

reply via email to

[Prev in Thread] Current Thread [Next in Thread]