OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [arm/] [lib1funcs.asm] - Blame information for rev 282

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
@ libgcc routines for ARM cpu.
2
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
3
 
4
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005, 2007, 2008,
5
   2009, 2010 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 3, or (at your option) any
10
later version.
11
 
12
This file is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
Under Section 7 of GPL version 3, you are granted additional
18
permissions described in the GCC Runtime Library Exception, version
19
3.1, as published by the Free Software Foundation.
20
 
21
You should have received a copy of the GNU General Public License and
22
a copy of the GCC Runtime Library Exception along with this program;
23
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24
.  */
25
 
26
/* An executable stack is *not* required for these functions.  */
27
#if defined(__ELF__) && defined(__linux__)
28
.section .note.GNU-stack,"",%progbits
29
.previous
30
#endif  /* __ELF__ and __linux__ */
31
 
32
#ifdef __ARM_EABI__
33
/* Some attributes that are common to all routines in this file.  */
34
        /* Tag_ABI_align8_needed: This code does not require 8-byte
35
           alignment from the caller.  */
36
        /* .eabi_attribute 24, 0  -- default setting.  */
37
        /* Tag_ABI_align8_preserved: This code preserves 8-byte
38
           alignment in any callee.  */
39
        .eabi_attribute 25, 1
40
#endif /* __ARM_EABI__ */
41
/* ------------------------------------------------------------------------ */
42
 
43
/* We need to know what prefix to add to function names.  */
44
 
45
#ifndef __USER_LABEL_PREFIX__
46
#error  __USER_LABEL_PREFIX__ not defined
47
#endif
48
 
49
/* ANSI concatenation macros.  */
50
 
51
#define CONCAT1(a, b) CONCAT2(a, b)
52
#define CONCAT2(a, b) a ## b
53
 
54
/* Use the right prefix for global labels.  */
55
 
56
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
57
 
58
#ifdef __ELF__
59
#ifdef __thumb__
60
#define __PLT__  /* Not supported in Thumb assembler (for now).  */
61
#elif defined __vxworks && !defined __PIC__
62
#define __PLT__ /* Not supported by the kernel loader.  */
63
#else
64
#define __PLT__ (PLT)
65
#endif
66
#define TYPE(x) .type SYM(x),function
67
#define SIZE(x) .size SYM(x), . - SYM(x)
68
#define LSYM(x) .x
69
#else
70
#define __PLT__
71
#define TYPE(x)
72
#define SIZE(x)
73
#define LSYM(x) x
74
#endif
75
 
76
/* Function end macros.  Variants for interworking.  */
77
 
78
#if defined(__ARM_ARCH_2__)
79
# define __ARM_ARCH__ 2
80
#endif
81
 
82
#if defined(__ARM_ARCH_3__)
83
# define __ARM_ARCH__ 3
84
#endif
85
 
86
#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
87
        || defined(__ARM_ARCH_4T__)
88
/* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
89
   long multiply instructions.  That includes v3M.  */
90
# define __ARM_ARCH__ 4
91
#endif
92
 
93
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
94
        || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
95
        || defined(__ARM_ARCH_5TEJ__)
96
# define __ARM_ARCH__ 5
97
#endif
98
 
99
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
100
        || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
101
        || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
102
        || defined(__ARM_ARCH_6M__)
103
# define __ARM_ARCH__ 6
104
#endif
105
 
106
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
107
        || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
108
# define __ARM_ARCH__ 7
109
#endif
110
 
111
#ifndef __ARM_ARCH__
112
#error Unable to determine architecture.
113
#endif
114
 
115
/* There are times when we might prefer Thumb1 code even if ARM code is
116
   permitted, for example, the code might be smaller, or there might be
117
   interworking problems with switching to ARM state if interworking is
118
   disabled.  */
119
#if (defined(__thumb__)                 \
120
     && !defined(__thumb2__)            \
121
     && (!defined(__THUMB_INTERWORK__)  \
122
         || defined (__OPTIMIZE_SIZE__) \
123
         || defined(__ARM_ARCH_6M__)))
124
# define __prefer_thumb__
125
#endif
126
 
127
/* How to return from a function call depends on the architecture variant.  */
128
 
129
#if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
130
 
131
# define RET            bx      lr
132
# define RETc(x)        bx##x   lr
133
 
134
/* Special precautions for interworking on armv4t.  */
135
# if (__ARM_ARCH__ == 4)
136
 
137
/* Always use bx, not ldr pc.  */
138
#  if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
139
#    define __INTERWORKING__
140
#   endif /* __THUMB__ || __THUMB_INTERWORK__ */
141
 
142
/* Include thumb stub before arm mode code.  */
143
#  if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
144
#   define __INTERWORKING_STUBS__
145
#  endif /* __thumb__ && !__THUMB_INTERWORK__ */
146
 
147
#endif /* __ARM_ARCH == 4 */
148
 
149
#else
150
 
151
# define RET            mov     pc, lr
152
# define RETc(x)        mov##x  pc, lr
153
 
154
#endif
155
 
156
.macro  cfi_pop         advance, reg, cfa_offset
157
#ifdef __ELF__
158
        .pushsection    .debug_frame
159
        .byte   0x4             /* DW_CFA_advance_loc4 */
160
        .4byte  \advance
161
        .byte   (0xc0 | \reg)   /* DW_CFA_restore */
162
        .byte   0xe             /* DW_CFA_def_cfa_offset */
163
        .uleb128 \cfa_offset
164
        .popsection
165
#endif
166
.endm
167
.macro  cfi_push        advance, reg, offset, cfa_offset
168
#ifdef __ELF__
169
        .pushsection    .debug_frame
170
        .byte   0x4             /* DW_CFA_advance_loc4 */
171
        .4byte  \advance
172
        .byte   (0x80 | \reg)   /* DW_CFA_offset */
173
        .uleb128 (\offset / -4)
174
        .byte   0xe             /* DW_CFA_def_cfa_offset */
175
        .uleb128 \cfa_offset
176
        .popsection
177
#endif
178
.endm
179
.macro cfi_start        start_label, end_label
180
#ifdef __ELF__
181
        .pushsection    .debug_frame
182
LSYM(Lstart_frame):
183
        .4byte  LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
184
LSYM(Lstart_cie):
185
        .4byte  0xffffffff      @ CIE Identifier Tag
186
        .byte   0x1     @ CIE Version
187
        .ascii  "\0"    @ CIE Augmentation
188
        .uleb128 0x1    @ CIE Code Alignment Factor
189
        .sleb128 -4     @ CIE Data Alignment Factor
190
        .byte   0xe     @ CIE RA Column
191
        .byte   0xc     @ DW_CFA_def_cfa
192
        .uleb128 0xd
193
        .uleb128 0x0
194
 
195
        .align 2
196
LSYM(Lend_cie):
197
        .4byte  LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
198
LSYM(Lstart_fde):
199
        .4byte  LSYM(Lstart_frame)      @ FDE CIE offset
200
        .4byte  \start_label    @ FDE initial location
201
        .4byte  \end_label-\start_label @ FDE address range
202
        .popsection
203
#endif
204
.endm
205
.macro cfi_end  end_label
206
#ifdef __ELF__
207
        .pushsection    .debug_frame
208
        .align  2
209
LSYM(Lend_fde):
210
        .popsection
211
\end_label:
212
#endif
213
.endm
214
 
215
/* Don't pass dirn, it's there just to get token pasting right.  */
216
 
217
.macro  RETLDM  regs=, cond=, unwind=, dirn=ia
218
#if defined (__INTERWORKING__)
219
        .ifc "\regs",""
220
        ldr\cond        lr, [sp], #8
221
        .else
222
# if defined(__thumb2__)
223
        pop\cond        {\regs, lr}
224
# else
225
        ldm\cond\dirn   sp!, {\regs, lr}
226
# endif
227
        .endif
228
        .ifnc "\unwind", ""
229
        /* Mark LR as restored.  */
230
97:     cfi_pop 97b - \unwind, 0xe, 0x0
231
        .endif
232
        bx\cond lr
233
#else
234
        /* Caller is responsible for providing IT instruction.  */
235
        .ifc "\regs",""
236
        ldr\cond        pc, [sp], #8
237
        .else
238
# if defined(__thumb2__)
239
        pop\cond        {\regs, pc}
240
# else
241
        ldm\cond\dirn   sp!, {\regs, pc}
242
# endif
243
        .endif
244
#endif
245
.endm
246
 
247
/* The Unified assembly syntax allows the same code to be assembled for both
248
   ARM and Thumb-2.  However this is only supported by recent gas, so define
249
   a set of macros to allow ARM code on older assemblers.  */
250
#if defined(__thumb2__)
251
.macro do_it cond, suffix=""
252
        it\suffix       \cond
253
.endm
254
.macro shift1 op, arg0, arg1, arg2
255
        \op     \arg0, \arg1, \arg2
256
.endm
257
#define do_push push
258
#define do_pop  pop
259
#define COND(op1, op2, cond) op1 ## op2 ## cond
260
/* Perform an arithmetic operation with a variable shift operand.  This
261
   requires two instructions and a scratch register on Thumb-2.  */
262
.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
263
        \shiftop \tmp, \src2, \shiftreg
264
        \name \dest, \src1, \tmp
265
.endm
266
#else
267
.macro do_it cond, suffix=""
268
.endm
269
.macro shift1 op, arg0, arg1, arg2
270
        mov     \arg0, \arg1, \op \arg2
271
.endm
272
#define do_push stmfd sp!,
273
#define do_pop  ldmfd sp!,
274
#define COND(op1, op2, cond) op1 ## cond ## op2
275
.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
276
        \name \dest, \src1, \src2, \shiftop \shiftreg
277
.endm
278
#endif
279
 
280
#ifdef __ARM_EABI__
281
.macro ARM_LDIV0 name signed
282
        cmp     r0, #0
283
        .ifc    \signed, unsigned
284
        movne   r0, #0xffffffff
285
        .else
286
        movgt   r0, #0x7fffffff
287
        movlt   r0, #0x80000000
288
        .endif
289
        b       SYM (__aeabi_idiv0) __PLT__
290
.endm
291
#else
292
.macro ARM_LDIV0 name signed
293
        str     lr, [sp, #-8]!
294
98:     cfi_push 98b - __\name, 0xe, -0x8, 0x8
295
        bl      SYM (__div0) __PLT__
296
        mov     r0, #0                  @ About as wrong as it could be.
297
        RETLDM  unwind=98b
298
.endm
299
#endif
300
 
301
 
302
#ifdef __ARM_EABI__
303
.macro THUMB_LDIV0 name signed
304
#if defined(__ARM_ARCH_6M__)
305
        .ifc \signed, unsigned
306
        cmp     r0, #0
307
        beq     1f
308
        mov     r0, #0
309
        mvn     r0, r0          @ 0xffffffff
310
1:
311
        .else
312
        cmp     r0, #0
313
        beq     2f
314
        blt     3f
315
        mov     r0, #0
316
        mvn     r0, r0
317
        lsr     r0, r0, #1      @ 0x7fffffff
318
        b       2f
319
3:      mov     r0, #0x80
320
        lsl     r0, r0, #24     @ 0x80000000
321
2:
322
        .endif
323
        push    {r0, r1, r2}
324
        ldr     r0, 4f
325
        adr     r1, 4f
326
        add     r0, r1
327
        str     r0, [sp, #8]
328
        @ We know we are not on armv4t, so pop pc is safe.
329
        pop     {r0, r1, pc}
330
        .align  2
331
4:
332
        .word   __aeabi_idiv0 - 4b
333
#elif defined(__thumb2__)
334
        .syntax unified
335
        .ifc \signed, unsigned
336
        cbz     r0, 1f
337
        mov     r0, #0xffffffff
338
1:
339
        .else
340
        cmp     r0, #0
341
        do_it   gt
342
        movgt   r0, #0x7fffffff
343
        do_it   lt
344
        movlt   r0, #0x80000000
345
        .endif
346
        b.w     SYM(__aeabi_idiv0) __PLT__
347
#else
348
        .align  2
349
        bx      pc
350
        nop
351
        .arm
352
        cmp     r0, #0
353
        .ifc    \signed, unsigned
354
        movne   r0, #0xffffffff
355
        .else
356
        movgt   r0, #0x7fffffff
357
        movlt   r0, #0x80000000
358
        .endif
359
        b       SYM(__aeabi_idiv0) __PLT__
360
        .thumb
361
#endif
362
.endm
363
#else
364
.macro THUMB_LDIV0 name signed
365
        push    { r1, lr }
366
98:     cfi_push 98b - __\name, 0xe, -0x4, 0x8
367
        bl      SYM (__div0)
368
        mov     r0, #0                  @ About as wrong as it could be.
369
#if defined (__INTERWORKING__)
370
        pop     { r1, r2 }
371
        bx      r2
372
#else
373
        pop     { r1, pc }
374
#endif
375
.endm
376
#endif
377
 
378
.macro FUNC_END name
379
        SIZE (__\name)
380
.endm
381
 
382
.macro DIV_FUNC_END name signed
383
        cfi_start       __\name, LSYM(Lend_div0)
384
LSYM(Ldiv0):
385
#ifdef __thumb__
386
        THUMB_LDIV0 \name \signed
387
#else
388
        ARM_LDIV0 \name \signed
389
#endif
390
        cfi_end LSYM(Lend_div0)
391
        FUNC_END \name
392
.endm
393
 
394
.macro THUMB_FUNC_START name
395
        .globl  SYM (\name)
396
        TYPE    (\name)
397
        .thumb_func
398
SYM (\name):
399
.endm
400
 
401
/* Function start macros.  Variants for ARM and Thumb.  */
402
 
403
#ifdef __thumb__
404
#define THUMB_FUNC .thumb_func
405
#define THUMB_CODE .force_thumb
406
# if defined(__thumb2__)
407
#define THUMB_SYNTAX .syntax divided
408
# else
409
#define THUMB_SYNTAX
410
# endif
411
#else
412
#define THUMB_FUNC
413
#define THUMB_CODE
414
#define THUMB_SYNTAX
415
#endif
416
 
417
.macro FUNC_START name
418
        .text
419
        .globl SYM (__\name)
420
        TYPE (__\name)
421
        .align 0
422
        THUMB_CODE
423
        THUMB_FUNC
424
        THUMB_SYNTAX
425
SYM (__\name):
426
.endm
427
 
428
/* Special function that will always be coded in ARM assembly, even if
429
   in Thumb-only compilation.  */
430
 
431
#if defined(__thumb2__)
432
 
433
/* For Thumb-2 we build everything in thumb mode.  */
434
.macro ARM_FUNC_START name
435
       FUNC_START \name
436
       .syntax unified
437
.endm
438
#define EQUIV .thumb_set
439
.macro  ARM_CALL name
440
        bl      __\name
441
.endm
442
 
443
#elif defined(__INTERWORKING_STUBS__)
444
 
445
.macro  ARM_FUNC_START name
446
        FUNC_START \name
447
        bx      pc
448
        nop
449
        .arm
450
/* A hook to tell gdb that we've switched to ARM mode.  Also used to call
451
   directly from other local arm routines.  */
452
_L__\name:
453
.endm
454
#define EQUIV .thumb_set
455
/* Branch directly to a function declared with ARM_FUNC_START.
456
   Must be called in arm mode.  */
457
.macro  ARM_CALL name
458
        bl      _L__\name
459
.endm
460
 
461
#else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
462
 
463
#ifdef __ARM_ARCH_6M__
464
#define EQUIV .thumb_set
465
#else
466
.macro  ARM_FUNC_START name
467
        .text
468
        .globl SYM (__\name)
469
        TYPE (__\name)
470
        .align 0
471
        .arm
472
SYM (__\name):
473
.endm
474
#define EQUIV .set
475
.macro  ARM_CALL name
476
        bl      __\name
477
.endm
478
#endif
479
 
480
#endif
481
 
482
.macro  FUNC_ALIAS new old
483
        .globl  SYM (__\new)
484
#if defined (__thumb__)
485
        .thumb_set      SYM (__\new), SYM (__\old)
486
#else
487
        .set    SYM (__\new), SYM (__\old)
488
#endif
489
.endm
490
 
491
#ifndef __ARM_ARCH_6M__
492
.macro  ARM_FUNC_ALIAS new old
493
        .globl  SYM (__\new)
494
        EQUIV   SYM (__\new), SYM (__\old)
495
#if defined(__INTERWORKING_STUBS__)
496
        .set    SYM (_L__\new), SYM (_L__\old)
497
#endif
498
.endm
499
#endif
500
 
501
#ifdef __ARMEB__
502
#define xxh r0
503
#define xxl r1
504
#define yyh r2
505
#define yyl r3
506
#else
507
#define xxh r1
508
#define xxl r0
509
#define yyh r3
510
#define yyl r2
511
#endif
512
 
513
#ifdef __ARM_EABI__
514
.macro  WEAK name
515
        .weak SYM (__\name)
516
.endm
517
#endif
518
 
519
#ifdef __thumb__
520
/* Register aliases.  */
521
 
522
work            .req    r4      @ XXXX is this safe ?
523
dividend        .req    r0
524
divisor         .req    r1
525
overdone        .req    r2
526
result          .req    r2
527
curbit          .req    r3
528
#endif
529
#if 0
530
ip              .req    r12
531
sp              .req    r13
532
lr              .req    r14
533
pc              .req    r15
534
#endif
535
 
536
/* ------------------------------------------------------------------------ */
537
/*              Bodies of the division and modulo routines.                 */
538
/* ------------------------------------------------------------------------ */
539
.macro ARM_DIV_BODY dividend, divisor, result, curbit
540
 
541
#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
542
 
543
#if defined (__thumb2__)
544
        clz     \curbit, \dividend
545
        clz     \result, \divisor
546
        sub     \curbit, \result, \curbit
547
        rsb     \curbit, \curbit, #31
548
        adr     \result, 1f
549
        add     \curbit, \result, \curbit, lsl #4
550
        mov     \result, #0
551
        mov     pc, \curbit
552
.p2align 3
553
1:
554
        .set    shift, 32
555
        .rept   32
556
        .set    shift, shift - 1
557
        cmp.w   \dividend, \divisor, lsl #shift
558
        nop.n
559
        adc.w   \result, \result, \result
560
        it      cs
561
        subcs.w \dividend, \dividend, \divisor, lsl #shift
562
        .endr
563
#else
564
        clz     \curbit, \dividend
565
        clz     \result, \divisor
566
        sub     \curbit, \result, \curbit
567
        rsbs    \curbit, \curbit, #31
568
        addne   \curbit, \curbit, \curbit, lsl #1
569
        mov     \result, #0
570
        addne   pc, pc, \curbit, lsl #2
571
        nop
572
        .set    shift, 32
573
        .rept   32
574
        .set    shift, shift - 1
575
        cmp     \dividend, \divisor, lsl #shift
576
        adc     \result, \result, \result
577
        subcs   \dividend, \dividend, \divisor, lsl #shift
578
        .endr
579
#endif
580
 
581
#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
582
#if __ARM_ARCH__ >= 5
583
 
584
        clz     \curbit, \divisor
585
        clz     \result, \dividend
586
        sub     \result, \curbit, \result
587
        mov     \curbit, #1
588
        mov     \divisor, \divisor, lsl \result
589
        mov     \curbit, \curbit, lsl \result
590
        mov     \result, #0
591
 
592
#else /* __ARM_ARCH__ < 5 */
593
 
594
        @ Initially shift the divisor left 3 bits if possible,
595
        @ set curbit accordingly.  This allows for curbit to be located
596
        @ at the left end of each 4-bit nibbles in the division loop
597
        @ to save one loop in most cases.
598
        tst     \divisor, #0xe0000000
599
        moveq   \divisor, \divisor, lsl #3
600
        moveq   \curbit, #8
601
        movne   \curbit, #1
602
 
603
        @ Unless the divisor is very big, shift it up in multiples of
604
        @ four bits, since this is the amount of unwinding in the main
605
        @ division loop.  Continue shifting until the divisor is
606
        @ larger than the dividend.
607
1:      cmp     \divisor, #0x10000000
608
        cmplo   \divisor, \dividend
609
        movlo   \divisor, \divisor, lsl #4
610
        movlo   \curbit, \curbit, lsl #4
611
        blo     1b
612
 
613
        @ For very big divisors, we must shift it a bit at a time, or
614
        @ we will be in danger of overflowing.
615
1:      cmp     \divisor, #0x80000000
616
        cmplo   \divisor, \dividend
617
        movlo   \divisor, \divisor, lsl #1
618
        movlo   \curbit, \curbit, lsl #1
619
        blo     1b
620
 
621
        mov     \result, #0
622
 
623
#endif /* __ARM_ARCH__ < 5 */
624
 
625
        @ Division loop
626
1:      cmp     \dividend, \divisor
627
        do_it   hs, t
628
        subhs   \dividend, \dividend, \divisor
629
        orrhs   \result,   \result,   \curbit
630
        cmp     \dividend, \divisor,  lsr #1
631
        do_it   hs, t
632
        subhs   \dividend, \dividend, \divisor, lsr #1
633
        orrhs   \result,   \result,   \curbit,  lsr #1
634
        cmp     \dividend, \divisor,  lsr #2
635
        do_it   hs, t
636
        subhs   \dividend, \dividend, \divisor, lsr #2
637
        orrhs   \result,   \result,   \curbit,  lsr #2
638
        cmp     \dividend, \divisor,  lsr #3
639
        do_it   hs, t
640
        subhs   \dividend, \dividend, \divisor, lsr #3
641
        orrhs   \result,   \result,   \curbit,  lsr #3
642
        cmp     \dividend, #0                   @ Early termination?
643
        do_it   hs, t
644
        movnes  \curbit,   \curbit,  lsr #4     @ No, any more bits to do?
645
        movne   \divisor,  \divisor, lsr #4
646
        bne     1b
647
 
648
#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
649
 
650
.endm
651
/* ------------------------------------------------------------------------ */
652
.macro ARM_DIV2_ORDER divisor, order
653
 
654
#if __ARM_ARCH__ >= 5
655
 
656
        clz     \order, \divisor
657
        rsb     \order, \order, #31
658
 
659
#else
660
 
661
        cmp     \divisor, #(1 << 16)
662
        movhs   \divisor, \divisor, lsr #16
663
        movhs   \order, #16
664
        movlo   \order, #0
665
 
666
        cmp     \divisor, #(1 << 8)
667
        movhs   \divisor, \divisor, lsr #8
668
        addhs   \order, \order, #8
669
 
670
        cmp     \divisor, #(1 << 4)
671
        movhs   \divisor, \divisor, lsr #4
672
        addhs   \order, \order, #4
673
 
674
        cmp     \divisor, #(1 << 2)
675
        addhi   \order, \order, #3
676
        addls   \order, \order, \divisor, lsr #1
677
 
678
#endif
679
 
680
.endm
681
/* ------------------------------------------------------------------------ */
682
.macro ARM_MOD_BODY dividend, divisor, order, spare
683
 
684
#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
685
 
686
        clz     \order, \divisor
687
        clz     \spare, \dividend
688
        sub     \order, \order, \spare
689
        rsbs    \order, \order, #31
690
        addne   pc, pc, \order, lsl #3
691
        nop
692
        .set    shift, 32
693
        .rept   32
694
        .set    shift, shift - 1
695
        cmp     \dividend, \divisor, lsl #shift
696
        subcs   \dividend, \dividend, \divisor, lsl #shift
697
        .endr
698
 
699
#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
700
#if __ARM_ARCH__ >= 5
701
 
702
        clz     \order, \divisor
703
        clz     \spare, \dividend
704
        sub     \order, \order, \spare
705
        mov     \divisor, \divisor, lsl \order
706
 
707
#else /* __ARM_ARCH__ < 5 */
708
 
709
        mov     \order, #0
710
 
711
        @ Unless the divisor is very big, shift it up in multiples of
712
        @ four bits, since this is the amount of unwinding in the main
713
        @ division loop.  Continue shifting until the divisor is
714
        @ larger than the dividend.
715
1:      cmp     \divisor, #0x10000000
716
        cmplo   \divisor, \dividend
717
        movlo   \divisor, \divisor, lsl #4
718
        addlo   \order, \order, #4
719
        blo     1b
720
 
721
        @ For very big divisors, we must shift it a bit at a time, or
722
        @ we will be in danger of overflowing.
723
1:      cmp     \divisor, #0x80000000
724
        cmplo   \divisor, \dividend
725
        movlo   \divisor, \divisor, lsl #1
726
        addlo   \order, \order, #1
727
        blo     1b
728
 
729
#endif /* __ARM_ARCH__ < 5 */
730
 
731
        @ Perform all needed substractions to keep only the reminder.
732
        @ Do comparisons in batch of 4 first.
733
        subs    \order, \order, #3              @ yes, 3 is intended here
734
        blt     2f
735
 
736
1:      cmp     \dividend, \divisor
737
        subhs   \dividend, \dividend, \divisor
738
        cmp     \dividend, \divisor,  lsr #1
739
        subhs   \dividend, \dividend, \divisor, lsr #1
740
        cmp     \dividend, \divisor,  lsr #2
741
        subhs   \dividend, \dividend, \divisor, lsr #2
742
        cmp     \dividend, \divisor,  lsr #3
743
        subhs   \dividend, \dividend, \divisor, lsr #3
744
        cmp     \dividend, #1
745
        mov     \divisor, \divisor, lsr #4
746
        subges  \order, \order, #4
747
        bge     1b
748
 
749
        tst     \order, #3
750
        teqne   \dividend, #0
751
        beq     5f
752
 
753
        @ Either 1, 2 or 3 comparison/substractions are left.
754
2:      cmn     \order, #2
755
        blt     4f
756
        beq     3f
757
        cmp     \dividend, \divisor
758
        subhs   \dividend, \dividend, \divisor
759
        mov     \divisor,  \divisor,  lsr #1
760
3:      cmp     \dividend, \divisor
761
        subhs   \dividend, \dividend, \divisor
762
        mov     \divisor,  \divisor,  lsr #1
763
4:      cmp     \dividend, \divisor
764
        subhs   \dividend, \dividend, \divisor
765
5:
766
 
767
#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
768
 
769
.endm
770
/* ------------------------------------------------------------------------ */
771
.macro THUMB_DIV_MOD_BODY modulo
772
        @ Load the constant 0x10000000 into our work register.
773
        mov     work, #1
774
        lsl     work, #28
775
LSYM(Loop1):
776
        @ Unless the divisor is very big, shift it up in multiples of
777
        @ four bits, since this is the amount of unwinding in the main
778
        @ division loop.  Continue shifting until the divisor is
779
        @ larger than the dividend.
780
        cmp     divisor, work
781
        bhs     LSYM(Lbignum)
782
        cmp     divisor, dividend
783
        bhs     LSYM(Lbignum)
784
        lsl     divisor, #4
785
        lsl     curbit,  #4
786
        b       LSYM(Loop1)
787
LSYM(Lbignum):
788
        @ Set work to 0x80000000
789
        lsl     work, #3
790
LSYM(Loop2):
791
        @ For very big divisors, we must shift it a bit at a time, or
792
        @ we will be in danger of overflowing.
793
        cmp     divisor, work
794
        bhs     LSYM(Loop3)
795
        cmp     divisor, dividend
796
        bhs     LSYM(Loop3)
797
        lsl     divisor, #1
798
        lsl     curbit,  #1
799
        b       LSYM(Loop2)
800
LSYM(Loop3):
801
        @ Test for possible subtractions ...
802
  .if \modulo
803
        @ ... On the final pass, this may subtract too much from the dividend,
804
        @ so keep track of which subtractions are done, we can fix them up
805
        @ afterwards.
806
        mov     overdone, #0
807
        cmp     dividend, divisor
808
        blo     LSYM(Lover1)
809
        sub     dividend, dividend, divisor
810
LSYM(Lover1):
811
        lsr     work, divisor, #1
812
        cmp     dividend, work
813
        blo     LSYM(Lover2)
814
        sub     dividend, dividend, work
815
        mov     ip, curbit
816
        mov     work, #1
817
        ror     curbit, work
818
        orr     overdone, curbit
819
        mov     curbit, ip
820
LSYM(Lover2):
821
        lsr     work, divisor, #2
822
        cmp     dividend, work
823
        blo     LSYM(Lover3)
824
        sub     dividend, dividend, work
825
        mov     ip, curbit
826
        mov     work, #2
827
        ror     curbit, work
828
        orr     overdone, curbit
829
        mov     curbit, ip
830
LSYM(Lover3):
831
        lsr     work, divisor, #3
832
        cmp     dividend, work
833
        blo     LSYM(Lover4)
834
        sub     dividend, dividend, work
835
        mov     ip, curbit
836
        mov     work, #3
837
        ror     curbit, work
838
        orr     overdone, curbit
839
        mov     curbit, ip
840
LSYM(Lover4):
841
        mov     ip, curbit
842
  .else
843
        @ ... and note which bits are done in the result.  On the final pass,
844
        @ this may subtract too much from the dividend, but the result will be ok,
845
        @ since the "bit" will have been shifted out at the bottom.
846
        cmp     dividend, divisor
847
        blo     LSYM(Lover1)
848
        sub     dividend, dividend, divisor
849
        orr     result, result, curbit
850
LSYM(Lover1):
851
        lsr     work, divisor, #1
852
        cmp     dividend, work
853
        blo     LSYM(Lover2)
854
        sub     dividend, dividend, work
855
        lsr     work, curbit, #1
856
        orr     result, work
857
LSYM(Lover2):
858
        lsr     work, divisor, #2
859
        cmp     dividend, work
860
        blo     LSYM(Lover3)
861
        sub     dividend, dividend, work
862
        lsr     work, curbit, #2
863
        orr     result, work
864
LSYM(Lover3):
865
        lsr     work, divisor, #3
866
        cmp     dividend, work
867
        blo     LSYM(Lover4)
868
        sub     dividend, dividend, work
869
        lsr     work, curbit, #3
870
        orr     result, work
871
LSYM(Lover4):
872
  .endif
873
 
874
        cmp     dividend, #0                    @ Early termination?
875
        beq     LSYM(Lover5)
876
        lsr     curbit,  #4                     @ No, any more bits to do?
877
        beq     LSYM(Lover5)
878
        lsr     divisor, #4
879
        b       LSYM(Loop3)
880
LSYM(Lover5):
881
  .if \modulo
882
        @ Any subtractions that we should not have done will be recorded in
883
        @ the top three bits of "overdone".  Exactly which were not needed
884
        @ are governed by the position of the bit, stored in ip.
885
        mov     work, #0xe
886
        lsl     work, #28
887
        and     overdone, work
888
        beq     LSYM(Lgot_result)
889
 
890
        @ If we terminated early, because dividend became zero, then the
891
        @ bit in ip will not be in the bottom nibble, and we should not
892
        @ perform the additions below.  We must test for this though
893
        @ (rather relying upon the TSTs to prevent the additions) since
894
        @ the bit in ip could be in the top two bits which might then match
895
        @ with one of the smaller RORs.
896
        mov     curbit, ip
897
        mov     work, #0x7
898
        tst     curbit, work
899
        beq     LSYM(Lgot_result)
900
 
901
        mov     curbit, ip
902
        mov     work, #3
903
        ror     curbit, work
904
        tst     overdone, curbit
905
        beq     LSYM(Lover6)
906
        lsr     work, divisor, #3
907
        add     dividend, work
908
LSYM(Lover6):
909
        mov     curbit, ip
910
        mov     work, #2
911
        ror     curbit, work
912
        tst     overdone, curbit
913
        beq     LSYM(Lover7)
914
        lsr     work, divisor, #2
915
        add     dividend, work
916
LSYM(Lover7):
917
        mov     curbit, ip
918
        mov     work, #1
919
        ror     curbit, work
920
        tst     overdone, curbit
921
        beq     LSYM(Lgot_result)
922
        lsr     work, divisor, #1
923
        add     dividend, work
924
  .endif
925
LSYM(Lgot_result):
926
.endm
927
/* ------------------------------------------------------------------------ */
928
/*              Start of the Real Functions                                 */
929
/* ------------------------------------------------------------------------ */
930
#ifdef L_udivsi3
931
 
932
#if defined(__prefer_thumb__)
933
 
934
        FUNC_START udivsi3
935
        FUNC_ALIAS aeabi_uidiv udivsi3
936
 
937
        cmp     divisor, #0
938
        beq     LSYM(Ldiv0)
939
LSYM(udivsi3_skip_div0_test):
940
        mov     curbit, #1
941
        mov     result, #0
942
 
943
        push    { work }
944
        cmp     dividend, divisor
945
        blo     LSYM(Lgot_result)
946
 
947
        THUMB_DIV_MOD_BODY 0
948
 
949
        mov     r0, result
950
        pop     { work }
951
        RET
952
 
953
#else /* ARM version/Thumb-2.  */
954
 
955
        ARM_FUNC_START udivsi3
956
        ARM_FUNC_ALIAS aeabi_uidiv udivsi3
957
 
958
        /* Note: if called via udivsi3_skip_div0_test, this will unnecessarily
959
           check for division-by-zero a second time.  */
960
LSYM(udivsi3_skip_div0_test):
961
        subs    r2, r1, #1
962
        do_it   eq
963
        RETc(eq)
964
        bcc     LSYM(Ldiv0)
965
        cmp     r0, r1
966
        bls     11f
967
        tst     r1, r2
968
        beq     12f
969
 
970
        ARM_DIV_BODY r0, r1, r2, r3
971
 
972
        mov     r0, r2
973
        RET
974
 
975
11:     do_it   eq, e
976
        moveq   r0, #1
977
        movne   r0, #0
978
        RET
979
 
980
12:     ARM_DIV2_ORDER r1, r2
981
 
982
        mov     r0, r0, lsr r2
983
        RET
984
 
985
#endif /* ARM version */
986
 
987
        DIV_FUNC_END udivsi3 unsigned
988
 
989
#if defined(__prefer_thumb__)
990
FUNC_START aeabi_uidivmod
991
        cmp     r1, #0
992
        beq     LSYM(Ldiv0)
993
        push    {r0, r1, lr}
994
        bl      LSYM(udivsi3_skip_div0_test)
995
        POP     {r1, r2, r3}
996
        mul     r2, r0
997
        sub     r1, r1, r2
998
        bx      r3
999
#else
1000
ARM_FUNC_START aeabi_uidivmod
1001
        cmp     r1, #0
1002
        beq     LSYM(Ldiv0)
1003
        stmfd   sp!, { r0, r1, lr }
1004
        bl      LSYM(udivsi3_skip_div0_test)
1005
        ldmfd   sp!, { r1, r2, lr }
1006
        mul     r3, r2, r0
1007
        sub     r1, r1, r3
1008
        RET
1009
#endif
1010
        FUNC_END aeabi_uidivmod
1011
 
1012
#endif /* L_udivsi3 */
1013
/* ------------------------------------------------------------------------ */
1014
#ifdef L_umodsi3
1015
 
1016
        FUNC_START umodsi3
1017
 
1018
#ifdef __thumb__
1019
 
1020
        cmp     divisor, #0
1021
        beq     LSYM(Ldiv0)
1022
        mov     curbit, #1
1023
        cmp     dividend, divisor
1024
        bhs     LSYM(Lover10)
1025
        RET
1026
 
1027
LSYM(Lover10):
1028
        push    { work }
1029
 
1030
        THUMB_DIV_MOD_BODY 1
1031
 
1032
        pop     { work }
1033
        RET
1034
 
1035
#else  /* ARM version.  */
1036
 
1037
        subs    r2, r1, #1                      @ compare divisor with 1
1038
        bcc     LSYM(Ldiv0)
1039
        cmpne   r0, r1                          @ compare dividend with divisor
1040
        moveq   r0, #0
1041
        tsthi   r1, r2                          @ see if divisor is power of 2
1042
        andeq   r0, r0, r2
1043
        RETc(ls)
1044
 
1045
        ARM_MOD_BODY r0, r1, r2, r3
1046
 
1047
        RET
1048
 
1049
#endif /* ARM version.  */
1050
 
1051
        DIV_FUNC_END umodsi3 unsigned
1052
 
1053
#endif /* L_umodsi3 */
1054
/* ------------------------------------------------------------------------ */
1055
#ifdef L_divsi3
1056
 
1057
#if defined(__prefer_thumb__)
1058
 
1059
        FUNC_START divsi3
1060
        FUNC_ALIAS aeabi_idiv divsi3
1061
 
1062
        cmp     divisor, #0
1063
        beq     LSYM(Ldiv0)
1064
LSYM(divsi3_skip_div0_test):
1065
        push    { work }
1066
        mov     work, dividend
1067
        eor     work, divisor           @ Save the sign of the result.
1068
        mov     ip, work
1069
        mov     curbit, #1
1070
        mov     result, #0
1071
        cmp     divisor, #0
1072
        bpl     LSYM(Lover10)
1073
        neg     divisor, divisor        @ Loops below use unsigned.
1074
LSYM(Lover10):
1075
        cmp     dividend, #0
1076
        bpl     LSYM(Lover11)
1077
        neg     dividend, dividend
1078
LSYM(Lover11):
1079
        cmp     dividend, divisor
1080
        blo     LSYM(Lgot_result)
1081
 
1082
        THUMB_DIV_MOD_BODY 0
1083
 
1084
        mov     r0, result
1085
        mov     work, ip
1086
        cmp     work, #0
1087
        bpl     LSYM(Lover12)
1088
        neg     r0, r0
1089
LSYM(Lover12):
1090
        pop     { work }
1091
        RET
1092
 
1093
#else /* ARM/Thumb-2 version.  */
1094
 
1095
        ARM_FUNC_START divsi3
1096
        ARM_FUNC_ALIAS aeabi_idiv divsi3
1097
 
1098
        cmp     r1, #0
1099
        beq     LSYM(Ldiv0)
1100
LSYM(divsi3_skip_div0_test):
1101
        eor     ip, r0, r1                      @ save the sign of the result.
1102
        do_it   mi
1103
        rsbmi   r1, r1, #0                      @ loops below use unsigned.
1104
        subs    r2, r1, #1                      @ division by 1 or -1 ?
1105
        beq     10f
1106
        movs    r3, r0
1107
        do_it   mi
1108
        rsbmi   r3, r0, #0                      @ positive dividend value
1109
        cmp     r3, r1
1110
        bls     11f
1111
        tst     r1, r2                          @ divisor is power of 2 ?
1112
        beq     12f
1113
 
1114
        ARM_DIV_BODY r3, r1, r0, r2
1115
 
1116
        cmp     ip, #0
1117
        do_it   mi
1118
        rsbmi   r0, r0, #0
1119
        RET
1120
 
1121
10:     teq     ip, r0                          @ same sign ?
1122
        do_it   mi
1123
        rsbmi   r0, r0, #0
1124
        RET
1125
 
1126
11:     do_it   lo
1127
        movlo   r0, #0
1128
        do_it   eq,t
1129
        moveq   r0, ip, asr #31
1130
        orreq   r0, r0, #1
1131
        RET
1132
 
1133
12:     ARM_DIV2_ORDER r1, r2
1134
 
1135
        cmp     ip, #0
1136
        mov     r0, r3, lsr r2
1137
        do_it   mi
1138
        rsbmi   r0, r0, #0
1139
        RET
1140
 
1141
#endif /* ARM version */
1142
 
1143
        DIV_FUNC_END divsi3 signed
1144
 
1145
#if defined(__prefer_thumb__)
1146
FUNC_START aeabi_idivmod
1147
        cmp     r1, #0
1148
        beq     LSYM(Ldiv0)
1149
        push    {r0, r1, lr}
1150
        bl      LSYM(divsi3_skip_div0_test)
1151
        POP     {r1, r2, r3}
1152
        mul     r2, r0
1153
        sub     r1, r1, r2
1154
        bx      r3
1155
#else
1156
ARM_FUNC_START aeabi_idivmod
1157
        cmp     r1, #0
1158
        beq     LSYM(Ldiv0)
1159
        stmfd   sp!, { r0, r1, lr }
1160
        bl      LSYM(divsi3_skip_div0_test)
1161
        ldmfd   sp!, { r1, r2, lr }
1162
        mul     r3, r2, r0
1163
        sub     r1, r1, r3
1164
        RET
1165
#endif
1166
        FUNC_END aeabi_idivmod
1167
 
1168
#endif /* L_divsi3 */
1169
/* ------------------------------------------------------------------------ */
1170
#ifdef L_modsi3
1171
 
1172
        FUNC_START modsi3
1173
 
1174
#ifdef __thumb__
1175
 
1176
        mov     curbit, #1
1177
        cmp     divisor, #0
1178
        beq     LSYM(Ldiv0)
1179
        bpl     LSYM(Lover10)
1180
        neg     divisor, divisor                @ Loops below use unsigned.
1181
LSYM(Lover10):
1182
        push    { work }
1183
        @ Need to save the sign of the dividend, unfortunately, we need
1184
        @ work later on.  Must do this after saving the original value of
1185
        @ the work register, because we will pop this value off first.
1186
        push    { dividend }
1187
        cmp     dividend, #0
1188
        bpl     LSYM(Lover11)
1189
        neg     dividend, dividend
1190
LSYM(Lover11):
1191
        cmp     dividend, divisor
1192
        blo     LSYM(Lgot_result)
1193
 
1194
        THUMB_DIV_MOD_BODY 1
1195
 
1196
        pop     { work }
1197
        cmp     work, #0
1198
        bpl     LSYM(Lover12)
1199
        neg     dividend, dividend
1200
LSYM(Lover12):
1201
        pop     { work }
1202
        RET
1203
 
1204
#else /* ARM version.  */
1205
 
1206
        cmp     r1, #0
1207
        beq     LSYM(Ldiv0)
1208
        rsbmi   r1, r1, #0                      @ loops below use unsigned.
1209
        movs    ip, r0                          @ preserve sign of dividend
1210
        rsbmi   r0, r0, #0                      @ if negative make positive
1211
        subs    r2, r1, #1                      @ compare divisor with 1
1212
        cmpne   r0, r1                          @ compare dividend with divisor
1213
        moveq   r0, #0
1214
        tsthi   r1, r2                          @ see if divisor is power of 2
1215
        andeq   r0, r0, r2
1216
        bls     10f
1217
 
1218
        ARM_MOD_BODY r0, r1, r2, r3
1219
 
1220
10:     cmp     ip, #0
1221
        rsbmi   r0, r0, #0
1222
        RET
1223
 
1224
#endif /* ARM version */
1225
 
1226
        DIV_FUNC_END modsi3 signed
1227
 
1228
#endif /* L_modsi3 */
1229
/* ------------------------------------------------------------------------ */
1230
#ifdef L_dvmd_tls
1231
 
1232
#ifdef __ARM_EABI__
1233
        WEAK aeabi_idiv0
1234
        WEAK aeabi_ldiv0
1235
        FUNC_START aeabi_idiv0
1236
        FUNC_START aeabi_ldiv0
1237
        RET
1238
        FUNC_END aeabi_ldiv0
1239
        FUNC_END aeabi_idiv0
1240
#else
1241
        FUNC_START div0
1242
        RET
1243
        FUNC_END div0
1244
#endif
1245
 
1246
#endif /* L_divmodsi_tools */
1247
/* ------------------------------------------------------------------------ */
1248
#ifdef L_dvmd_lnx
1249
@ GNU/Linux division-by zero handler.  Used in place of L_dvmd_tls
1250
 
1251
/* Constant taken from .  */
1252
#define SIGFPE  8
1253
 
1254
#ifdef __ARM_EABI__
1255
        WEAK aeabi_idiv0
1256
        WEAK aeabi_ldiv0
1257
        ARM_FUNC_START aeabi_idiv0
1258
        ARM_FUNC_START aeabi_ldiv0
1259
#else
1260
        ARM_FUNC_START div0
1261
#endif
1262
 
1263
        do_push {r1, lr}
1264
        mov     r0, #SIGFPE
1265
        bl      SYM(raise) __PLT__
1266
        RETLDM  r1
1267
 
1268
#ifdef __ARM_EABI__
1269
        FUNC_END aeabi_ldiv0
1270
        FUNC_END aeabi_idiv0
1271
#else
1272
        FUNC_END div0
1273
#endif
1274
 
1275
#endif /* L_dvmd_lnx */
1276
#ifdef L_clear_cache
1277
#if defined __ARM_EABI__ && defined __linux__
1278
@ EABI GNU/Linux call to cacheflush syscall.
1279
        ARM_FUNC_START clear_cache
1280
        do_push {r7}
1281
#if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
1282
        movw    r7, #2
1283
        movt    r7, #0xf
1284
#else
1285
        mov     r7, #0xf0000
1286
        add     r7, r7, #2
1287
#endif
1288
        mov     r2, #0
1289
        swi     0
1290
        do_pop  {r7}
1291
        RET
1292
        FUNC_END clear_cache
1293
#else
1294
#error "This is only for ARM EABI GNU/Linux"
1295
#endif
1296
#endif /* L_clear_cache */
1297
/* ------------------------------------------------------------------------ */
1298
/* Dword shift operations.  */
1299
/* All the following Dword shift variants rely on the fact that
1300
        shft xxx, Reg
1301
   is in fact done as
1302
        shft xxx, (Reg & 255)
1303
   so for Reg value in (32...63) and (-1...-31) we will get zero (in the
1304
   case of logical shifts) or the sign (for asr).  */
1305
 
1306
#ifdef __ARMEB__
1307
#define al      r1
1308
#define ah      r0
1309
#else
1310
#define al      r0
1311
#define ah      r1
1312
#endif
1313
 
1314
/* Prevent __aeabi double-word shifts from being produced on SymbianOS.  */
1315
#ifndef __symbian__
1316
 
1317
#ifdef L_lshrdi3
1318
 
1319
        FUNC_START lshrdi3
1320
        FUNC_ALIAS aeabi_llsr lshrdi3
1321
 
1322
#ifdef __thumb__
1323
        lsr     al, r2
1324
        mov     r3, ah
1325
        lsr     ah, r2
1326
        mov     ip, r3
1327
        sub     r2, #32
1328
        lsr     r3, r2
1329
        orr     al, r3
1330
        neg     r2, r2
1331
        mov     r3, ip
1332
        lsl     r3, r2
1333
        orr     al, r3
1334
        RET
1335
#else
1336
        subs    r3, r2, #32
1337
        rsb     ip, r2, #32
1338
        movmi   al, al, lsr r2
1339
        movpl   al, ah, lsr r3
1340
        orrmi   al, al, ah, lsl ip
1341
        mov     ah, ah, lsr r2
1342
        RET
1343
#endif
1344
        FUNC_END aeabi_llsr
1345
        FUNC_END lshrdi3
1346
 
1347
#endif
1348
 
1349
#ifdef L_ashrdi3
1350
 
1351
        FUNC_START ashrdi3
1352
        FUNC_ALIAS aeabi_lasr ashrdi3
1353
 
1354
#ifdef __thumb__
1355
        lsr     al, r2
1356
        mov     r3, ah
1357
        asr     ah, r2
1358
        sub     r2, #32
1359
        @ If r2 is negative at this point the following step would OR
1360
        @ the sign bit into all of AL.  That's not what we want...
1361
        bmi     1f
1362
        mov     ip, r3
1363
        asr     r3, r2
1364
        orr     al, r3
1365
        mov     r3, ip
1366
1:
1367
        neg     r2, r2
1368
        lsl     r3, r2
1369
        orr     al, r3
1370
        RET
1371
#else
1372
        subs    r3, r2, #32
1373
        rsb     ip, r2, #32
1374
        movmi   al, al, lsr r2
1375
        movpl   al, ah, asr r3
1376
        orrmi   al, al, ah, lsl ip
1377
        mov     ah, ah, asr r2
1378
        RET
1379
#endif
1380
 
1381
        FUNC_END aeabi_lasr
1382
        FUNC_END ashrdi3
1383
 
1384
#endif
1385
 
1386
#ifdef L_ashldi3
1387
 
1388
        FUNC_START ashldi3
1389
        FUNC_ALIAS aeabi_llsl ashldi3
1390
 
1391
#ifdef __thumb__
1392
        lsl     ah, r2
1393
        mov     r3, al
1394
        lsl     al, r2
1395
        mov     ip, r3
1396
        sub     r2, #32
1397
        lsl     r3, r2
1398
        orr     ah, r3
1399
        neg     r2, r2
1400
        mov     r3, ip
1401
        lsr     r3, r2
1402
        orr     ah, r3
1403
        RET
1404
#else
1405
        subs    r3, r2, #32
1406
        rsb     ip, r2, #32
1407
        movmi   ah, ah, lsl r2
1408
        movpl   ah, al, lsl r3
1409
        orrmi   ah, ah, al, lsr ip
1410
        mov     al, al, lsl r2
1411
        RET
1412
#endif
1413
        FUNC_END aeabi_llsl
1414
        FUNC_END ashldi3
1415
 
1416
#endif
1417
 
1418
#endif /* __symbian__ */
1419
 
1420
#if ((__ARM_ARCH__ > 5) && !defined(__ARM_ARCH_6M__)) \
1421
    || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
1422
    || defined(__ARM_ARCH_5TEJ__)
1423
#define HAVE_ARM_CLZ 1
1424
#endif
1425
 
1426
#ifdef L_clzsi2
1427
#if defined(__ARM_ARCH_6M__)
1428
FUNC_START clzsi2
1429
        mov     r1, #28
1430
        mov     r3, #1
1431
        lsl     r3, r3, #16
1432
        cmp     r0, r3 /* 0x10000 */
1433
        bcc     2f
1434
        lsr     r0, r0, #16
1435
        sub     r1, r1, #16
1436
2:      lsr     r3, r3, #8
1437
        cmp     r0, r3 /* #0x100 */
1438
        bcc     2f
1439
        lsr     r0, r0, #8
1440
        sub     r1, r1, #8
1441
2:      lsr     r3, r3, #4
1442
        cmp     r0, r3 /* #0x10 */
1443
        bcc     2f
1444
        lsr     r0, r0, #4
1445
        sub     r1, r1, #4
1446
2:      adr     r2, 1f
1447
        ldrb    r0, [r2, r0]
1448
        add     r0, r0, r1
1449
        bx lr
1450
.align 2
1451
1:
1452
.byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1453
        FUNC_END clzsi2
1454
#else
1455
ARM_FUNC_START clzsi2
1456
# if defined(HAVE_ARM_CLZ)
1457
        clz     r0, r0
1458
        RET
1459
# else
1460
        mov     r1, #28
1461
        cmp     r0, #0x10000
1462
        do_it   cs, t
1463
        movcs   r0, r0, lsr #16
1464
        subcs   r1, r1, #16
1465
        cmp     r0, #0x100
1466
        do_it   cs, t
1467
        movcs   r0, r0, lsr #8
1468
        subcs   r1, r1, #8
1469
        cmp     r0, #0x10
1470
        do_it   cs, t
1471
        movcs   r0, r0, lsr #4
1472
        subcs   r1, r1, #4
1473
        adr     r2, 1f
1474
        ldrb    r0, [r2, r0]
1475
        add     r0, r0, r1
1476
        RET
1477
.align 2
1478
1:
1479
.byte 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
1480
# endif /* !HAVE_ARM_CLZ */
1481
        FUNC_END clzsi2
1482
#endif
1483
#endif /* L_clzsi2 */
1484
 
1485
#ifdef L_clzdi2
1486
#if !defined(HAVE_ARM_CLZ)
1487
 
1488
# if defined(__ARM_ARCH_6M__)
1489
FUNC_START clzdi2
1490
        push    {r4, lr}
1491
# else
1492
ARM_FUNC_START clzdi2
1493
        do_push {r4, lr}
1494
# endif
1495
        cmp     xxh, #0
1496
        bne     1f
1497
# ifdef __ARMEB__
1498
        mov     r0, xxl
1499
        bl      __clzsi2
1500
        add     r0, r0, #32
1501
        b 2f
1502
1:
1503
        bl      __clzsi2
1504
# else
1505
        bl      __clzsi2
1506
        add     r0, r0, #32
1507
        b 2f
1508
1:
1509
        mov     r0, xxh
1510
        bl      __clzsi2
1511
# endif
1512
2:
1513
# if defined(__ARM_ARCH_6M__)
1514
        pop     {r4, pc}
1515
# else
1516
        RETLDM  r4
1517
# endif
1518
        FUNC_END clzdi2
1519
 
1520
#else /* HAVE_ARM_CLZ */
1521
 
1522
ARM_FUNC_START clzdi2
1523
        cmp     xxh, #0
1524
        do_it   eq, et
1525
        clzeq   r0, xxl
1526
        clzne   r0, xxh
1527
        addeq   r0, r0, #32
1528
        RET
1529
        FUNC_END clzdi2
1530
 
1531
#endif
1532
#endif /* L_clzdi2 */
1533
 
1534
/* ------------------------------------------------------------------------ */
1535
/* These next two sections are here despite the fact that they contain Thumb
1536
   assembler because their presence allows interworked code to be linked even
1537
   when the GCC library is this one.  */
1538
 
1539
/* Do not build the interworking functions when the target architecture does
1540
   not support Thumb instructions.  (This can be a multilib option).  */
1541
#if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
1542
      || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
1543
      || __ARM_ARCH__ >= 6
1544
 
1545
#if defined L_call_via_rX
1546
 
1547
/* These labels & instructions are used by the Arm/Thumb interworking code.
1548
   The address of function to be called is loaded into a register and then
1549
   one of these labels is called via a BL instruction.  This puts the
1550
   return address into the link register with the bottom bit set, and the
1551
   code here switches to the correct mode before executing the function.  */
1552
 
1553
        .text
1554
        .align 0
1555
        .force_thumb
1556
 
1557
.macro call_via register
1558
        THUMB_FUNC_START _call_via_\register
1559
 
1560
        bx      \register
1561
        nop
1562
 
1563
        SIZE    (_call_via_\register)
1564
.endm
1565
 
1566
        call_via r0
1567
        call_via r1
1568
        call_via r2
1569
        call_via r3
1570
        call_via r4
1571
        call_via r5
1572
        call_via r6
1573
        call_via r7
1574
        call_via r8
1575
        call_via r9
1576
        call_via sl
1577
        call_via fp
1578
        call_via ip
1579
        call_via sp
1580
        call_via lr
1581
 
1582
#endif /* L_call_via_rX */
1583
 
1584
/* Don't bother with the old interworking routines for Thumb-2.  */
1585
/* ??? Maybe only omit these on "m" variants.  */
1586
#if !defined(__thumb2__) && !defined(__ARM_ARCH_6M__)
1587
 
1588
#if defined L_interwork_call_via_rX
1589
 
1590
/* These labels & instructions are used by the Arm/Thumb interworking code,
1591
   when the target address is in an unknown instruction set.  The address
1592
   of function to be called is loaded into a register and then one of these
1593
   labels is called via a BL instruction.  This puts the return address
1594
   into the link register with the bottom bit set, and the code here
1595
   switches to the correct mode before executing the function.  Unfortunately
1596
   the target code cannot be relied upon to return via a BX instruction, so
1597
   instead we have to store the resturn address on the stack and allow the
1598
   called function to return here instead.  Upon return we recover the real
1599
   return address and use a BX to get back to Thumb mode.
1600
 
1601
   There are three variations of this code.  The first,
1602
   _interwork_call_via_rN(), will push the return address onto the
1603
   stack and pop it in _arm_return().  It should only be used if all
1604
   arguments are passed in registers.
1605
 
1606
   The second, _interwork_r7_call_via_rN(), instead stores the return
1607
   address at [r7, #-4].  It is the caller's responsibility to ensure
1608
   that this address is valid and contains no useful data.
1609
 
1610
   The third, _interwork_r11_call_via_rN(), works in the same way but
1611
   uses r11 instead of r7.  It is useful if the caller does not really
1612
   need a frame pointer.  */
1613
 
1614
        .text
1615
        .align 0
1616
 
1617
        .code   32
1618
        .globl _arm_return
1619
LSYM(Lstart_arm_return):
1620
        cfi_start       LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
1621
        cfi_push        0, 0xe, -0x8, 0x8
1622
        nop     @ This nop is for the benefit of debuggers, so that
1623
                @ backtraces will use the correct unwind information.
1624
_arm_return:
1625
        RETLDM  unwind=LSYM(Lstart_arm_return)
1626
        cfi_end LSYM(Lend_arm_return)
1627
 
1628
        .globl _arm_return_r7
1629
_arm_return_r7:
1630
        ldr     lr, [r7, #-4]
1631
        bx      lr
1632
 
1633
        .globl _arm_return_r11
1634
_arm_return_r11:
1635
        ldr     lr, [r11, #-4]
1636
        bx      lr
1637
 
1638
.macro interwork_with_frame frame, register, name, return
1639
        .code   16
1640
 
1641
        THUMB_FUNC_START \name
1642
 
1643
        bx      pc
1644
        nop
1645
 
1646
        .code   32
1647
        tst     \register, #1
1648
        streq   lr, [\frame, #-4]
1649
        adreq   lr, _arm_return_\frame
1650
        bx      \register
1651
 
1652
        SIZE    (\name)
1653
.endm
1654
 
1655
.macro interwork register
1656
        .code   16
1657
 
1658
        THUMB_FUNC_START _interwork_call_via_\register
1659
 
1660
        bx      pc
1661
        nop
1662
 
1663
        .code   32
1664
        .globl LSYM(Lchange_\register)
1665
LSYM(Lchange_\register):
1666
        tst     \register, #1
1667
        streq   lr, [sp, #-8]!
1668
        adreq   lr, _arm_return
1669
        bx      \register
1670
 
1671
        SIZE    (_interwork_call_via_\register)
1672
 
1673
        interwork_with_frame r7,\register,_interwork_r7_call_via_\register
1674
        interwork_with_frame r11,\register,_interwork_r11_call_via_\register
1675
.endm
1676
 
1677
        interwork r0
1678
        interwork r1
1679
        interwork r2
1680
        interwork r3
1681
        interwork r4
1682
        interwork r5
1683
        interwork r6
1684
        interwork r7
1685
        interwork r8
1686
        interwork r9
1687
        interwork sl
1688
        interwork fp
1689
        interwork ip
1690
        interwork sp
1691
 
1692
        /* The LR case has to be handled a little differently...  */
1693
        .code 16
1694
 
1695
        THUMB_FUNC_START _interwork_call_via_lr
1696
 
1697
        bx      pc
1698
        nop
1699
 
1700
        .code 32
1701
        .globl .Lchange_lr
1702
.Lchange_lr:
1703
        tst     lr, #1
1704
        stmeqdb r13!, {lr, pc}
1705
        mov     ip, lr
1706
        adreq   lr, _arm_return
1707
        bx      ip
1708
 
1709
        SIZE    (_interwork_call_via_lr)
1710
 
1711
#endif /* L_interwork_call_via_rX */
1712
#endif /* !__thumb2__ */
1713
 
1714
/* Functions to support compact pic switch tables in thumb1 state.
1715
   All these routines take an index into the table in r0.  The
1716
   table is at LR & ~1 (but this must be rounded up in the case
1717
   of 32-bit entires).  They are only permitted to clobber r12
1718
   and r14 and r0 must be preserved on exit.  */
1719
#ifdef L_thumb1_case_sqi
1720
 
1721
        .text
1722
        .align 0
1723
        .force_thumb
1724
        .syntax unified
1725
        THUMB_FUNC_START __gnu_thumb1_case_sqi
1726
        push    {r1}
1727
        mov     r1, lr
1728
        lsrs    r1, r1, #1
1729
        lsls    r1, r1, #1
1730
        ldrsb   r1, [r1, r0]
1731
        lsls    r1, r1, #1
1732
        add     lr, lr, r1
1733
        pop     {r1}
1734
        bx      lr
1735
        SIZE (__gnu_thumb1_case_sqi)
1736
#endif
1737
 
1738
#ifdef L_thumb1_case_uqi
1739
 
1740
        .text
1741
        .align 0
1742
        .force_thumb
1743
        .syntax unified
1744
        THUMB_FUNC_START __gnu_thumb1_case_uqi
1745
        push    {r1}
1746
        mov     r1, lr
1747
        lsrs    r1, r1, #1
1748
        lsls    r1, r1, #1
1749
        ldrb    r1, [r1, r0]
1750
        lsls    r1, r1, #1
1751
        add     lr, lr, r1
1752
        pop     {r1}
1753
        bx      lr
1754
        SIZE (__gnu_thumb1_case_uqi)
1755
#endif
1756
 
1757
#ifdef L_thumb1_case_shi
1758
 
1759
        .text
1760
        .align 0
1761
        .force_thumb
1762
        .syntax unified
1763
        THUMB_FUNC_START __gnu_thumb1_case_shi
1764
        push    {r0, r1}
1765
        mov     r1, lr
1766
        lsrs    r1, r1, #1
1767
        lsls    r0, r0, #1
1768
        lsls    r1, r1, #1
1769
        ldrsh   r1, [r1, r0]
1770
        lsls    r1, r1, #1
1771
        add     lr, lr, r1
1772
        pop     {r0, r1}
1773
        bx      lr
1774
        SIZE (__gnu_thumb1_case_shi)
1775
#endif
1776
 
1777
#ifdef L_thumb1_case_uhi
1778
 
1779
        .text
1780
        .align 0
1781
        .force_thumb
1782
        .syntax unified
1783
        THUMB_FUNC_START __gnu_thumb1_case_uhi
1784
        push    {r0, r1}
1785
        mov     r1, lr
1786
        lsrs    r1, r1, #1
1787
        lsls    r0, r0, #1
1788
        lsls    r1, r1, #1
1789
        ldrh    r1, [r1, r0]
1790
        lsls    r1, r1, #1
1791
        add     lr, lr, r1
1792
        pop     {r0, r1}
1793
        bx      lr
1794
        SIZE (__gnu_thumb1_case_uhi)
1795
#endif
1796
 
1797
#ifdef L_thumb1_case_si
1798
 
1799
        .text
1800
        .align 0
1801
        .force_thumb
1802
        .syntax unified
1803
        THUMB_FUNC_START __gnu_thumb1_case_si
1804
        push    {r0, r1}
1805
        mov     r1, lr
1806
        adds.n  r1, r1, #2      /* Align to word.  */
1807
        lsrs    r1, r1, #2
1808
        lsls    r0, r0, #2
1809
        lsls    r1, r1, #2
1810
        ldr     r0, [r1, r0]
1811
        adds    r0, r0, r1
1812
        mov     lr, r0
1813
        pop     {r0, r1}
1814
        mov     pc, lr          /* We know we were called from thumb code.  */
1815
        SIZE (__gnu_thumb1_case_si)
1816
#endif
1817
 
1818
#endif /* Arch supports thumb.  */
1819
 
1820
#ifndef __symbian__
1821
#ifndef __ARM_ARCH_6M__
1822
#include "ieee754-df.S"
1823
#include "ieee754-sf.S"
1824
#include "bpabi.S"
1825
#else /* __ARM_ARCH_6M__ */
1826
#include "bpabi-v6m.S"
1827
#endif /* __ARM_ARCH_6M__ */
1828
#endif /* !__symbian__ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.