Annotation of gcc/config/h8300/lib1funcs.asm, revision 1.1.1.1

1.1       root        1: ;; libgcc1 routines for the Hitachi h8/300 cpu.
                      2: ;; Contributed by Steve Chamberlain.
                      3: ;; [email protected]
                      4: 
                      5: /* Copyright (C) 1994 Free Software Foundation, Inc.
                      6: 
                      7: This file is free software; you can redistribute it and/or modify it
                      8: under the terms of the GNU General Public License as published by the
                      9: Free Software Foundation; either version 2, or (at your option) any
                     10: later version.
                     11: 
                     12: In addition to the permissions in the GNU General Public License, the
                     13: Free Software Foundation gives you unlimited permission to link the
                     14: compiled version of this file with other programs, and to distribute
                     15: those programs without any restriction coming from the use of this
                     16: file.  (The General Public License restrictions do apply in other
                     17: respects; for example, they cover modification of the file, and
                     18: distribution when not linked into another program.)
                     19: 
                     20: This file is distributed in the hope that it will be useful, but
                     21: WITHOUT ANY WARRANTY; without even the implied warranty of
                     22: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     23: General Public License for more details.
                     24: 
                     25: You should have received a copy of the GNU General Public License
                     26: along with this program; see the file COPYING.  If not, write to
                     27: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     28: 
                     29: /* As a special exception, if you link this library with other files,
                     30:    some of which are compiled with GCC, to produce an executable,
                     31:    this library does not by itself cause the resulting executable
                     32:    to be covered by the GNU General Public License.
                     33:    This exception does not however invalidate any other reasons why
                     34:    the executable file might be covered by the GNU General Public License.  */
                     35: 
                     36: /* Assembler register definitions.  */
                     37: 
                     38: #define A0 r0
                     39: #define A0L r0l
                     40: #define A0H r0h
                     41: 
                     42: #define A1 r1
                     43: #define A1L r1l
                     44: #define A1H r1h
                     45: 
                     46: #define A2 r2
                     47: #define A2L r2l
                     48: #define A2H r2h
                     49: 
                     50: #define A3 r3
                     51: #define A3L r3l
                     52: #define A3H r3h
                     53: 
                     54: #define S0 r4
                     55: #define S0L r4l
                     56: #define S0H r4h
                     57: 
                     58: #define S1 r5
                     59: #define S1L r5l
                     60: #define S1H r5h
                     61: 
                     62: #define S2 r6
                     63: #define S2L r6l
                     64: #define S2H r6h
                     65: 
                     66: #ifdef __H8300__
                     67: #define MOVP   mov.w   /* pointers are 16 bits */
                     68: #define ADDP   add.w
                     69: #define CMPP   cmp.w
                     70: #define PUSHP  push
                     71: #define POPP   pop
                     72: 
                     73: #define A0P    r0
                     74: #define A1P    r1
                     75: #define A2P    r2
                     76: #define A3P    r3
                     77: #define S0P    r4
                     78: #define S1P    r5
                     79: #define S2P    r6
                     80: #endif
                     81: 
                     82: #ifdef __H8300H__
                     83: #define MOVP   mov.l   /* pointers are 32 bits */
                     84: #define ADDP   add.l
                     85: #define CMPP   cmp.l
                     86: #define PUSHP  push.l
                     87: #define POPP   pop.l
                     88: 
                     89: #define A0P    er0
                     90: #define A1P    er1
                     91: #define A2P    er2
                     92: #define A3P    er3
                     93: #define S0P    er4
                     94: #define S1P    er5
                     95: #define S2P    er6
                     96: 
                     97: #define A0E    e0
                     98: #define A1E    e1
                     99: #define A2E    e2
                    100: #define A3E    e3
                    101: #endif
                    102: 
                    103: #ifdef L_cmpsi2
                    104: #ifdef __H8300__
                    105:        .section .text
                    106:        .align 2
                    107:        .global ___cmpsi2
                    108: ___cmpsi2:
                    109:        cmp.w   A2,A0
                    110:        bne     .L2
                    111:        cmp.w   A3,A1
                    112:        bne     .L2
                    113:        mov.w   #1,A0
                    114:        rts
                    115: .L2:
                    116:        cmp.w   A0,A2
                    117:        bgt     .L4
                    118:        bne     .L3
                    119:        cmp.w   A1,A3
                    120:        bls     .L3
                    121: .L4:
                    122:        sub.w   A0,A0
                    123:        rts
                    124: .L3:
                    125:        mov.w   #2,A0
                    126: .L5:
                    127:        rts
                    128:        .end
                    129: #endif
                    130: #endif /* L_cmpsi2 */
                    131: 
                    132: #ifdef L_ucmpsi2
                    133: #ifdef __H8300__
                    134:        .section .text
                    135:        .align 2
                    136:        .global ___ucmpsi2
                    137: ___ucmpsi2:
                    138:        cmp.w   A2,A0
                    139:        bne     .L2
                    140:        cmp.w   A3,A1
                    141:        bne     .L2
                    142:        mov.w   #1,A0
                    143:        rts
                    144: .L2:
                    145:        cmp.w   A0,A2
                    146:        bhi     .L4
                    147:        bne     .L3
                    148:        cmp.w   A1,A3
                    149:        bls     .L3
                    150: .L4:
                    151:        sub.w   A0,A0
                    152:        rts
                    153: .L3:
                    154:        mov.w   #2,A0
                    155: .L5:
                    156:        rts
                    157:        .end
                    158: #endif
                    159: #endif /* L_ucmpsi2 */
                    160: 
                    161: #ifdef L_divhi3
                    162: 
                    163: ;; HImode divides for the H8/300.
                    164: ;; We bunch all of this into one object file since there are several
                    165: ;; "supporting routines".
                    166: 
                    167: ; general purpose normalize routine
                    168: ; 
                    169: ; divisor in A0
                    170: ; dividend in A1
                    171: ; turns both into +ve numbers, and leaves what the answer sign
                    172: ; should be in A2L
                    173: 
                    174: #ifdef __H8300__
                    175:        .section .text
                    176:        .align 2
                    177: divnorm:
                    178:        mov.b   #0x0,A2L
                    179:        or      A0H,A0H         ; is divisor > 0
                    180:        bge     _lab1                   
                    181:        not     A0H             ; no - then make it +ve
                    182:        not     A0L
                    183:        adds    #1,A0                   
                    184:        xor     #0x1,A2L        ; and remember that in A2L
                    185: _lab1: or      A1H,A1H ; look at dividend
                    186:        bge     _lab2           
                    187:        not     A1H             ; it is -ve, make it positive
                    188:        not     A1L
                    189:        adds    #1,A1
                    190:        xor     #0x1,A2L; and toggle sign of result
                    191: _lab2: rts
                    192: 
                    193: ; A0=A0/A1 signed
                    194: 
                    195:        .global ___divhi3
                    196: ___divhi3:
                    197:        bsr     divnorm
                    198:        bsr     ___udivhi3
                    199: negans:        or      A2L,A2L ; should answer be negative ?
                    200:        beq     _lab4
                    201:        not     A0H     ; yes, so make it so
                    202:        not     A0L
                    203:        adds    #1,A0
                    204: _lab4: rts     
                    205: 
                    206: ; A0=A0%A1 signed
                    207: 
                    208:        .global ___modhi3
                    209: ___modhi3:
                    210:        bsr     divnorm
                    211:        bsr     ___udivhi3
                    212:        mov     A3,A0
                    213:        bra     negans
                    214: 
                    215: ; A0=A0%A1 unsigned
                    216: 
                    217:        .global ___umodhi3
                    218: ___umodhi3:
                    219:        bsr     ___udivhi3
                    220:        mov     A3,A0
                    221:        rts
                    222: 
                    223: ; A0=A0/A1 unsigned
                    224: ; A3=A0%A1 unsigned
                    225: ; A2H trashed
                    226: ; D high 8 bits of denom
                    227: ; d low 8 bits of denom
                    228: ; N high 8 bits of num
                    229: ; n low 8 bits of num
                    230: ; M high 8 bits of mod
                    231: ; m low 8 bits of mod
                    232: ; Q high 8 bits of quot
                    233: ; q low 8 bits of quot
                    234: ; P preserve
                    235: 
                    236: ; The h8 only has a 16/8 bit divide, so we look at the incoming and
                    237: ; see how to partition up the expression.
                    238: 
                    239:        .global ___udivhi3
                    240: ___udivhi3:
                    241:                                ; A0 A1 A2 A3 
                    242:                                ; Nn Dd       P
                    243:        sub.w   A3,A3           ; Nn Dd xP 00 
                    244:        or      A1H,A1H          
                    245:        bne     divlongway
                    246:        or      A0H,A0H         
                    247:        beq     _lab6           
                    248: 
                    249: ; we know that D == 0 and N is != 0
                    250:        mov.b   A0H,A3L         ; Nn Dd xP 0N
                    251:        divxu   A1L,A3          ;          MQ
                    252:        mov.b   A3L,A0H         ; Q
                    253: ; dealt with N, do n
                    254: _lab6: mov.b   A0L,A3L         ;           n
                    255:        divxu   A1L,A3          ;          mq
                    256:        mov.b   A3L,A0L         ; Qq
                    257:        mov.b   A3H,A3L         ;           m
                    258:        mov.b   #0x0,A3H        ; Qq       0m
                    259:        rts     
                    260: 
                    261: ; D != 0 - which means the denominator is
                    262: ;          loop around to get the result.
                    263: 
                    264: divlongway:
                    265:        mov.b   A0H,A3L         ; Nn Dd xP 0N
                    266:        mov.b   #0x0,A0H        ; high byte of answer has to be zero
                    267:        mov.b   #0x8,A2H        ;       8
                    268: div8:  add.b   A0L,A0L         ; n*=2
                    269:        rotxl   A3L             ; Make remainder bigger
                    270:        rotxl   A3H             
                    271:        sub.w   A1,A3           ; Q-=N
                    272:        bhs     setbit          ; set a bit ?
                    273:        add.w   A1,A3           ;  no : too far , Q+=N
                    274: 
                    275:        dec     A2H             
                    276:        bne     div8            ; next bit      
                    277:        rts     
                    278: 
                    279: setbit:        inc     A0L             ; do insert bit
                    280:        dec     A2H             
                    281:        bne     div8            ; next bit      
                    282:        rts     
                    283: 
                    284: #endif /* __H8300__ */
                    285: #endif /* L_divhi3 */
                    286: 
                    287: #ifdef L_divsi3
                    288: 
                    289: ;; 4 byte integer divides for the H8/300.
                    290: ;;
                    291: ;; We have one routine which does all the work and lots of 
                    292: ;; little ones which prepare the args and massage the sign.
                    293: ;; We bunch all of this into one object file since there are several
                    294: ;; "supporting routines".
                    295: 
                    296: #ifdef __H8300H__
                    297:        .h8300h
                    298: #endif
                    299: 
                    300:        .section .text
                    301:        .align 2
                    302: 
                    303: ; Put abs SIs into r0/r1 and r2/r3, and leave a 1 in r6l with sign of rest.
                    304: ; This function is here to keep branch displacements small.
                    305: 
                    306: #ifdef __H8300__
                    307: 
                    308: divnorm:
                    309:        mov.b   #0,S2L          ; keep the sign in S2
                    310:        mov.b   A0H,A0H         ; is the numerator -ve
                    311:        bge     postive
                    312: 
                    313:        ; negate arg
                    314:        not     A0H
                    315:        not     A1H
                    316:        not     A0L
                    317:        not     A1L
                    318: 
                    319:        add     #1,A1L
                    320:        addx    #0,A1H
                    321:        addx    #0,A0H
                    322:        addx    #0,A0L
                    323: 
                    324:        mov.b   #1,S2L          ; the sign will be -ve
                    325: postive:
                    326:        mov.b   A2H,A2H         ; is the denominator -ve
                    327:        bge     postive2
                    328:        not     A2L             
                    329:        not     A2H
                    330:        not     A3L
                    331:        not     A3H
                    332:        add.b   #1,A3L  
                    333:        addx    #0,A3H
                    334:        addx    #0,A2L
                    335:        addx    #0,A2H
                    336:        xor     #1,S2L          ; toggle result sign
                    337: postive2:
                    338:        rts
                    339: 
                    340: #else /* __H8300H__ */
                    341: 
                    342: divnorm:
                    343:        mov.b   #0,S2L          ; keep the sign in S2
                    344:        mov.l   A0P,A0P         ; is the numerator -ve
                    345:        bge     postive
                    346: 
                    347:        neg.l   A0P             ; negate arg
                    348:        mov.b   #1,S2L          ; the sign will be -ve
                    349: 
                    350: postive:
                    351:        mov.l   A1P,A1P         ; is the denominator -ve
                    352:        bge     postive2
                    353: 
                    354:        neg.l   A1P             ; negate arg
                    355:        xor.b   #1,S2L          ; toggle result sign
                    356: 
                    357: postive2:
                    358:        rts
                    359: 
                    360: #endif
                    361: 
                    362: ; numerator in A0/A1
                    363: ; denominator in A2/A3
                    364:        .global ___modsi3
                    365: ___modsi3:
                    366:        PUSHP   S2P             
                    367:        PUSHP   S0P
                    368:        PUSHP   S1P
                    369: 
                    370:        bsr     divnorm
                    371:        bsr     divmodsi4
                    372: #ifdef __H8300__
                    373:        mov     S0,A0
                    374:        mov     S1,A1
                    375: #else
                    376:        mov.l   S0P,A0P
                    377: #endif
                    378:        bra     exitdiv
                    379: 
                    380:        .global ___udivsi3
                    381: ___udivsi3:
                    382:        PUSHP   S2P
                    383:        PUSHP   S0P
                    384:        PUSHP   S1P
                    385:        mov.b   #0,S2L  ; keep sign low
                    386:        bsr     divmodsi4
                    387:        bra     exitdiv
                    388: 
                    389:        .global ___umodsi3
                    390: ___umodsi3:
                    391:        PUSHP   S2P
                    392:        PUSHP   S0P
                    393:        PUSHP   S1P
                    394:        mov.b   #0,S2L  ; keep sign low
                    395:        bsr     divmodsi4
                    396: #ifdef __H8300__
                    397:        mov     S0,A0
                    398:        mov     S1,A1
                    399: #else
                    400:        mov.l   S0P,A0P
                    401: #endif
                    402:        bra     exitdiv
                    403:        
                    404:        .global ___divsi3
                    405: ___divsi3:
                    406:        PUSHP   S2P
                    407:        PUSHP   S0P
                    408:        PUSHP   S1P
                    409:        jsr     divnorm
                    410:        jsr     divmodsi4
                    411: 
                    412:        ; examine what the sign should be
                    413: exitdiv:
                    414:        POPP    S1P
                    415:        POPP    S0P
                    416: 
                    417:        or      S2L,S2L
                    418:        beq     reti
                    419:        
                    420:        ; should be -ve
                    421: #ifdef __H8300__
                    422:        not     A0H
                    423:        not     A1H
                    424:        not     A0L
                    425:        not     A1L
                    426: 
                    427:        add     #1,A1L
                    428:        addx    #0,A1H
                    429:        addx    #0,A0H
                    430:        addx    #0,A0L
                    431: #else /* __H8300H__ */
                    432:        neg.l   A0P
                    433: #endif
                    434: 
                    435: reti:
                    436:        POPP    S2P
                    437:        rts     
                    438: 
                    439:        ; takes A0/A1 numerator (A0P for 300h)
                    440:        ; A2/A3 denominator (A1P for 300h)
                    441:        ; returns A0/A1 quotient (A0P for 300h)
                    442:        ; S0/S1 remainder (S0P for 300h)
                    443:        ; trashes S2
                    444: 
                    445: #ifdef __H8300__
                    446: 
                    447: divmodsi4:
                    448:         sub.w  S0,S0           ; zero play area
                    449:         mov.w  S0,S1
                    450:         mov.b  A2H,S2H
                    451:         or     A2L,S2H
                    452:         or     A3H,S2H
                    453:         bne    DenHighZero
                    454:         mov.b  A0H,A0H
                    455:         bne    NumByte0Zero
                    456:         mov.b  A0L,A0L
                    457:         bne    NumByte1Zero
                    458:         mov.b  A1H,A1H
                    459:         bne    NumByte2Zero
                    460:         bra    NumByte3Zero
                    461: NumByte0Zero:
                    462:        mov.b   A0H,S1L
                    463:         divxu  A3L,S1
                    464:         mov.b  S1L,A0H
                    465: NumByte1Zero:
                    466:        mov.b   A0L,S1L
                    467:         divxu  A3L,S1
                    468:         mov.b  S1L,A0L
                    469: NumByte2Zero:
                    470:        mov.b   A1H,S1L
                    471:         divxu  A3L,S1
                    472:         mov.b  S1L,A1H
                    473: NumByte3Zero:
                    474:        mov.b   A1L,S1L
                    475:         divxu  A3L,S1
                    476:         mov.b  S1L,A1L
                    477: 
                    478:         mov.b  S1H,S1L
                    479:         mov.b  #0x0,S1H
                    480:         rts    
                    481: 
                    482: ; have to do the divide by shift and test
                    483: DenHighZero:
                    484:        mov.b   A0H,S1L
                    485:         mov.b  A0L,A0H
                    486:         mov.b  A1H,A0L
                    487:         mov.b  A1L,A1H
                    488: 
                    489:         mov.b  #0,A1L
                    490:         mov.b  #24,S2H ; only do 24 iterations
                    491: 
                    492: nextbit:
                    493:        add.w   A1,A1   ; double the answer guess
                    494:         rotxl  A0L
                    495:         rotxl  A0H
                    496: 
                    497:         rotxl  S1L     ; double remainder
                    498:         rotxl  S1H
                    499:         rotxl  S0L
                    500:         rotxl  S0H
                    501:         sub.w  A3,S1   ; does it all fit
                    502:         subx   A2L,S0L
                    503:         subx   A2H,S0H
                    504:         bhs    setone   
                    505: 
                    506:         add.w  A3,S1   ; no, restore mistake
                    507:         addx   A2L,S0L
                    508:         addx   A2H,S0H
                    509: 
                    510:         dec    S2H
                    511:         bne    nextbit
                    512:         rts    
                    513:        
                    514: setone:
                    515:        inc     A1L
                    516:         dec    S2H
                    517:         bne    nextbit
                    518:         rts    
                    519: 
                    520: #else /* __H8300H__ */
                    521: 
                    522: divmodsi4:
                    523:        sub.l   S0P,S0P         ; zero play area
                    524:        mov.w   A1E,A1E         ; denominator top word 0?
                    525:        bne     DenHighZero
                    526: 
                    527:        ; do it the easy way, see page 107 in manual
                    528:        mov.w   A0E,A2
                    529:        extu.l  A2P
                    530:        divxu.w A1,A2P
                    531:        mov.w   A2E,A0E
                    532:        divxu.w A1,A0P
                    533:        mov.w   A0E,S0
                    534:        mov.w   A2,A0E
                    535:        extu.l  S0P
                    536:        rts
                    537: 
                    538: DenHighZero:
                    539:        mov.w   A0E,A2
                    540:        mov.b   A2H,S0L
                    541:        mov.b   A2L,A2H
                    542:        mov.b   A0H,A2L
                    543:        mov.w   A2,A0E
                    544:        mov.b   A0L,A0H
                    545:        mov.b   #0,A0L
                    546:        mov.b   #24,S2H         ; only do 24 iterations
                    547: 
                    548: nextbit:
                    549:        shll.l  A0P             ; double the answer guess
                    550:        rotxl.l S0P             ; double remainder
                    551:        sub.l   A1P,S0P         ; does it all fit?
                    552:        bhs     setone
                    553: 
                    554:        add.l   A1P,S0P         ; no, restore mistake
                    555:        dec     S2H
                    556:        bne     nextbit
                    557:        rts
                    558: 
                    559: setone:
                    560:        inc     A0L
                    561:        dec     S2H
                    562:        bne     nextbit
                    563:        rts
                    564: 
                    565: #endif
                    566: #endif /* L_divsi3 */
                    567: 
                    568: #ifdef L_mulhi3
                    569: 
                    570: ;; HImode multiply.
                    571: ; The h8 only has an 8*8->16 multiply.
                    572: ; The answer is the same as:
                    573: ; 
                    574: ; product = (srca.l * srcb.l) + ((srca.h * srcb.l) + (srcb.h * srca.l)) * 256
                    575: ; (we can ignore A1.h * A0.h cause that will all off the top)
                    576: ; A0 in
                    577: ; A1 in 
                    578: ; A0 answer
                    579: 
                    580: #ifdef __H8300__
                    581:        .section .text
                    582:        .align 2
                    583:        .global ___mulhi3
                    584: ___mulhi3:
                    585:        mov.b   A1L,A2L         ; A2l gets srcb.l
                    586:        mulxu   A0L,A2          ; A2 gets first sub product 
                    587: 
                    588:        mov.b   A0H,A3L         ; prepare for
                    589:        mulxu   A1L,A3          ; second sub product
                    590: 
                    591:        add.b   A3L,A2H         ; sum first two terms
                    592: 
                    593:        mov.b   A1H,A3L         ; third sub product
                    594:        mulxu   A0L,A3          
                    595: 
                    596:        add.b   A3L,A2H         ; almost there
                    597:        mov.w   A2,A0           ; that is
                    598:        rts
                    599: 
                    600: #endif
                    601: #endif /* L_mulhi3 */
                    602: 
                    603: #ifdef L_mulsi3
                    604: 
                    605: ;; SImode multiply.
                    606: ;; 
                    607: ;; I think that shift and add may be sufficient for this.  Using the
                    608: ;; supplied 8x8->16 would need 10 ops of 14 cycles each + overhead.  This way
                    609: ;; the inner loop uses maybe 20 cycles + overhead, but terminates
                    610: ;; quickly on small args.
                    611: ;;
                    612: ;; A0/A1 src_a
                    613: ;; A2/A3 src_b
                    614: ;;
                    615: ;;  while (a) 
                    616: ;;    {
                    617: ;;      if (a & 1)
                    618: ;;        r += b;
                    619: ;;      a >>= 1;
                    620: ;;      b <<= 1;
                    621: ;;    }
                    622: 
                    623:        .section .text
                    624:        .align 2
                    625: 
                    626: #ifdef __H8300__
                    627: 
                    628:        .global ___mulsi3
                    629: ___mulsi3:
                    630:        PUSHP   S0P
                    631:        PUSHP   S1P
                    632:        PUSHP   S2P
                    633:        
                    634:        sub.w   S0,S0
                    635:        sub.w   S1,S1
                    636:        
                    637:        ; while (a)
                    638: _top:  mov.w   A0,A0
                    639:        bne     _more
                    640:        mov.w   A1,A1
                    641:        beq     _done
                    642: _more: ; if (a & 1)
                    643:        bld     #0,A1L
                    644:        bcc     _nobit
                    645:        ; r += b
                    646:        add.w   A3,S1
                    647:        addx    A2L,S0L
                    648:        addx    A2H,S0H
                    649: _nobit:
                    650:        ; a >>= 1
                    651:        shlr    A0H
                    652:        rotxr   A0L
                    653:        rotxr   A1H
                    654:        rotxr   A1L
                    655:        
                    656:        ; b <<= 1
                    657:        add.w   A3,A3
                    658:        addx    A2L,A2L
                    659:        addx    A2H,A2H
                    660:        bra     _top
                    661: 
                    662: _done:
                    663:        mov.w   S0,A0   
                    664:        mov.w   S1,A1
                    665:        POPP    S2P
                    666:        POPP    S1P
                    667:        POPP    S0P
                    668:        rts
                    669: 
                    670: #else /* __H8300H__ */
                    671: 
                    672:        .h8300h
                    673: 
                    674:        .global ___mulsi3
                    675: ___mulsi3:
                    676:        sub.l   A2P,A2P
                    677: 
                    678:        ; while (a)
                    679: _top:  mov.l   A0P,A0P
                    680:        beq     _done
                    681: 
                    682:        ; if (a & 1)
                    683:        bld     #0,A0L
                    684:        bcc     _nobit
                    685: 
                    686:        ; r += b
                    687:        add.l   A1P,A2P
                    688: 
                    689: _nobit:
                    690:        ; a >>= 1
                    691:        shlr.l  A0P
                    692: 
                    693:        ; b <<= 1
                    694:        shll.l  A1P
                    695:        bra     _top
                    696: 
                    697: _done:
                    698:        mov.l   A2P,A0P
                    699:        rts
                    700: 
                    701: #endif
                    702: #endif /* L_mulsi3 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.