~ubuntu-branches/ubuntu/trusty/oss4/trusty-proposed

« back to all changes in this revision

Viewing changes to setup/Linux/arm/lib1funcs.asm

  • Committer: Bazaar Package Importer
  • Author(s): Romain Beauxis, Samuel Thibault, Romain Beauxis, Sebastien NOEL
  • Date: 2011-06-14 10:06:56 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110614100656-cx4oc7u426zn812z
Tags: 4.2-build2004-1
[ Samuel Thibault ]
* debian/control: Add liboss4-salsa2, liboss4-salsa-dev and
  liboss4-salsa-asound2 packages, equivalent to (and will replace) those from
  the oss-libsalsa package (Closes: #589127).
* debian/patches/liboss4-salsa.patch: New patch to rename libsalsa into
  liboss4-salsa to avoid conflicts in the archive for no good reason.
* debian/rules: Make in libOSSlib and libsalsa.
* debian/liboss4-salsa-dev.install, debian/liboss4-salsa2.install,
  debian/liboss4-salsa-asound2.links, debian/liboss4-salsa-dev.links:
  Install liboss4-salsa libraries like was done in the oss-libsalsa package.
* include-alsa: Add a copy of ALSA 1.0.5 headers: Cf ALSA_1.0.* symbols in
  libsalsa, this is the roughly supported version.
* debian/copyright: Update for new include-alsa files.
* alsa.pc: New file for compatibility with libasound-dev.
* debian/control:
  - Add Vcs-Browser and Vcs-Svn fields.
  - Use linux-any instead of the list of Linux archs (Closes: #604679).
  - Make dkms dependency linux-any only.
* debian/patches/hurd_iot.patch: New patch to fix soundcard.h usage in
  libsalsa on hurd-i386.
* debian/patches/libsalsa_fixes.patch: New patch to fix some printf usages
  and ioctl declaration in libsalsa.
* debian/patches/no_EBADE.patch: New patch to cope with hurd-i386 not having
  EBADE.
* debian/patches/CFLAGS.patch: New patch to make oss4 take debian/rules
  CFLAGS into account.
* debian/patches/snd_asoundlib_version.patch: New patch to add
  snd_asoundlib_version().
* debian/patches/generic_srccconf.patch: New patch to fix source
  configuration on unknown archs.

[ Romain Beauxis ]
* Fixed README.Debian to only mention dkms' modules.
* Switch to dpkg-source 3.0 (quilt) format
* Added DM-Upload-Allowed: yes

[ Sebastien NOEL ]
* New upstream release (Closes: #595298, #619272).
* Fix typo in initscript (Closes: #627149).
* debian/control: adjust linux-headers dependencies (Closes: #628879).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
@ 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
 
5
   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 into combinations with other programs,
 
15
and to distribute those combinations without any restriction coming
 
16
from the use of this file.  (The General Public License restrictions
 
17
do apply in other respects; for example, they cover modification of
 
18
the file, and distribution when not linked into a combine
 
19
executable.)
 
20
 
 
21
This file is distributed in the hope that it will be useful, but
 
22
WITHOUT ANY WARRANTY; without even the implied warranty of
 
23
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
24
General Public License for more details.
 
25
 
 
26
You should have received a copy of the GNU General Public License
 
27
along with this program; see the file COPYING.  If not, write to
 
28
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
 
29
Boston, MA 02110-1301, USA.  */
 
30
 
 
31
/* An executable stack is *not* required for these functions.  */
 
32
#if defined(__ELF__) && defined(__linux__)
 
33
.section .note.GNU-stack,"",%progbits
 
34
.previous
 
35
#endif
 
36
 
 
37
/* ------------------------------------------------------------------------ */
 
38
 
 
39
/* We need to know what prefix to add to function names.  */
 
40
 
 
41
#ifndef __USER_LABEL_PREFIX__
 
42
#error  __USER_LABEL_PREFIX__ not defined
 
43
#endif
 
44
 
 
45
/* ANSI concatenation macros.  */
 
46
 
 
47
#define CONCAT1(a, b) CONCAT2(a, b)
 
48
#define CONCAT2(a, b) a ## b
 
49
 
 
50
/* Use the right prefix for global labels.  */
 
51
 
 
52
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
 
53
 
 
54
#ifdef __ELF__
 
55
#ifdef __thumb__
 
56
#define __PLT__  /* Not supported in Thumb assembler (for now).  */
 
57
#elif defined __vxworks && !defined __PIC__
 
58
#define __PLT__ /* Not supported by the kernel loader.  */
 
59
#else
 
60
#define __PLT__ (PLT)
 
61
#endif
 
62
#define TYPE(x) .type SYM(x),function
 
63
#define SIZE(x) .size SYM(x), . - SYM(x)
 
64
#define LSYM(x) .x
 
65
#else
 
66
#define __PLT__
 
67
#define TYPE(x)
 
68
#define SIZE(x)
 
69
#define LSYM(x) x
 
70
#endif
 
71
 
 
72
/* Function end macros.  Variants for interworking.  */
 
73
 
 
74
#if defined(__ARM_ARCH_2__)
 
75
# define __ARM_ARCH__ 2
 
76
#endif
 
77
 
 
78
#if defined(__ARM_ARCH_3__)
 
79
# define __ARM_ARCH__ 3
 
80
#endif
 
81
 
 
82
#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
 
83
        || defined(__ARM_ARCH_4T__)
 
84
/* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
 
85
   long multiply instructions.  That includes v3M.  */
 
86
# define __ARM_ARCH__ 4
 
87
#endif
 
88
        
 
89
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
 
90
        || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
 
91
        || defined(__ARM_ARCH_5TEJ__)
 
92
# define __ARM_ARCH__ 5
 
93
#endif
 
94
 
 
95
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
 
96
        || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
 
97
        || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__)
 
98
# define __ARM_ARCH__ 6
 
99
#endif
 
100
 
 
101
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
 
102
        || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__)
 
103
# define __ARM_ARCH__ 7
 
104
#endif
 
105
 
 
106
#ifndef __ARM_ARCH__
 
107
#error Unable to determine architecture.
 
108
#endif
 
109
 
 
110
/* How to return from a function call depends on the architecture variant.  */
 
111
 
 
112
#if (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
 
113
 
 
114
# define RET            bx      lr
 
115
# define RETc(x)        bx##x   lr
 
116
 
 
117
/* Special precautions for interworking on armv4t.  */
 
118
# if (__ARM_ARCH__ == 4)
 
119
 
 
120
/* Always use bx, not ldr pc.  */
 
121
#  if (defined(__thumb__) || defined(__THUMB_INTERWORK__))
 
122
#    define __INTERWORKING__
 
123
#   endif /* __THUMB__ || __THUMB_INTERWORK__ */
 
124
 
 
125
/* Include thumb stub before arm mode code.  */
 
126
#  if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
 
127
#   define __INTERWORKING_STUBS__
 
128
#  endif /* __thumb__ && !__THUMB_INTERWORK__ */
 
129
 
 
130
#endif /* __ARM_ARCH == 4 */
 
131
 
 
132
#else
 
133
 
 
134
# define RET            mov     pc, lr
 
135
# define RETc(x)        mov##x  pc, lr
 
136
 
 
137
#endif
 
138
 
 
139
.macro  cfi_pop         advance, reg, cfa_offset
 
140
#ifdef __ELF__
 
141
        .pushsection    .debug_frame
 
142
        .byte   0x4             /* DW_CFA_advance_loc4 */
 
143
        .4byte  \advance
 
144
        .byte   (0xc0 | \reg)   /* DW_CFA_restore */
 
145
        .byte   0xe             /* DW_CFA_def_cfa_offset */
 
146
        .uleb128 \cfa_offset
 
147
        .popsection
 
148
#endif
 
149
.endm
 
150
.macro  cfi_push        advance, reg, offset, cfa_offset
 
151
#ifdef __ELF__
 
152
        .pushsection    .debug_frame
 
153
        .byte   0x4             /* DW_CFA_advance_loc4 */
 
154
        .4byte  \advance
 
155
        .byte   (0x80 | \reg)   /* DW_CFA_offset */
 
156
        .uleb128 (\offset / -4)
 
157
        .byte   0xe             /* DW_CFA_def_cfa_offset */
 
158
        .uleb128 \cfa_offset
 
159
        .popsection
 
160
#endif
 
161
.endm
 
162
.macro cfi_start        start_label, end_label
 
163
#ifdef __ELF__
 
164
        .pushsection    .debug_frame
 
165
LSYM(Lstart_frame):
 
166
        .4byte  LSYM(Lend_cie) - LSYM(Lstart_cie) @ Length of CIE
 
167
LSYM(Lstart_cie):
 
168
        .4byte  0xffffffff      @ CIE Identifier Tag
 
169
        .byte   0x1     @ CIE Version
 
170
        .ascii  "\0"    @ CIE Augmentation
 
171
        .uleb128 0x1    @ CIE Code Alignment Factor
 
172
        .sleb128 -4     @ CIE Data Alignment Factor
 
173
        .byte   0xe     @ CIE RA Column
 
174
        .byte   0xc     @ DW_CFA_def_cfa
 
175
        .uleb128 0xd
 
176
        .uleb128 0x0
 
177
 
 
178
        .align 2
 
179
LSYM(Lend_cie):
 
180
        .4byte  LSYM(Lend_fde)-LSYM(Lstart_fde) @ FDE Length
 
181
LSYM(Lstart_fde):
 
182
        .4byte  LSYM(Lstart_frame)      @ FDE CIE offset
 
183
        .4byte  \start_label    @ FDE initial location
 
184
        .4byte  \end_label-\start_label @ FDE address range
 
185
        .popsection
 
186
#endif
 
187
.endm
 
188
.macro cfi_end  end_label
 
189
#ifdef __ELF__
 
190
        .pushsection    .debug_frame
 
191
        .align  2
 
192
LSYM(Lend_fde):
 
193
        .popsection
 
194
\end_label:
 
195
#endif
 
196
.endm
 
197
 
 
198
/* Don't pass dirn, it's there just to get token pasting right.  */
 
199
 
 
200
.macro  RETLDM  regs=, cond=, unwind=, dirn=ia
 
201
#if defined (__INTERWORKING__)
 
202
        .ifc "\regs",""
 
203
        ldr\cond        lr, [sp], #8
 
204
        .else
 
205
# if defined(__thumb2__)
 
206
        pop\cond        {\regs, lr}
 
207
# else
 
208
        ldm\cond\dirn   sp!, {\regs, lr}
 
209
# endif
 
210
        .endif
 
211
        .ifnc "\unwind", ""
 
212
        /* Mark LR as restored.  */
 
213
97:     cfi_pop 97b - \unwind, 0xe, 0x0
 
214
        .endif
 
215
        bx\cond lr
 
216
#else
 
217
        /* Caller is responsible for providing IT instruction.  */
 
218
        .ifc "\regs",""
 
219
        ldr\cond        pc, [sp], #8
 
220
        .else
 
221
# if defined(__thumb2__)
 
222
        pop\cond        {\regs, pc}
 
223
# else
 
224
        ldm\cond\dirn   sp!, {\regs, pc}
 
225
# endif
 
226
        .endif
 
227
#endif
 
228
.endm
 
229
 
 
230
/* The Unified assembly syntax allows the same code to be assembled for both
 
231
   ARM and Thumb-2.  However this is only supported by recent gas, so define
 
232
   a set of macros to allow ARM code on older assemblers.  */
 
233
#if defined(__thumb2__)
 
234
.macro do_it cond, suffix=""
 
235
        it\suffix       \cond
 
236
.endm
 
237
.macro shift1 op, arg0, arg1, arg2
 
238
        \op     \arg0, \arg1, \arg2
 
239
.endm
 
240
#define do_push push
 
241
#define do_pop  pop
 
242
#define COND(op1, op2, cond) op1 ## op2 ## cond
 
243
/* Perform an arithmetic operation with a variable shift operand.  This
 
244
   requires two instructions and a scratch register on Thumb-2.  */
 
245
.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
 
246
        \shiftop \tmp, \src2, \shiftreg
 
247
        \name \dest, \src1, \tmp
 
248
.endm
 
249
#else
 
250
.macro do_it cond, suffix=""
 
251
.endm
 
252
.macro shift1 op, arg0, arg1, arg2
 
253
        mov     \arg0, \arg1, \op \arg2
 
254
.endm
 
255
#define do_push stmfd sp!,
 
256
#define do_pop  ldmfd sp!,
 
257
#define COND(op1, op2, cond) op1 ## cond ## op2
 
258
.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp
 
259
        \name \dest, \src1, \src2, \shiftop \shiftreg
 
260
.endm
 
261
#endif
 
262
 
 
263
.macro ARM_LDIV0 name
 
264
        str     lr, [sp, #-8]!
 
265
98:     cfi_push 98b - __\name, 0xe, -0x8, 0x8
 
266
        bl      SYM (__div0) __PLT__
 
267
        mov     r0, #0                  @ About as wrong as it could be.
 
268
        RETLDM  unwind=98b
 
269
.endm
 
270
 
 
271
 
 
272
.macro THUMB_LDIV0 name
 
273
        push    { r1, lr }
 
274
98:     cfi_push 98b - __\name, 0xe, -0x4, 0x8
 
275
        bl      SYM (__div0)
 
276
        mov     r0, #0                  @ About as wrong as it could be.
 
277
#if defined (__INTERWORKING__)
 
278
        pop     { r1, r2 }
 
279
        bx      r2
 
280
#else
 
281
        pop     { r1, pc }
 
282
#endif
 
283
.endm
 
284
 
 
285
.macro FUNC_END name
 
286
        SIZE (__\name)
 
287
.endm
 
288
 
 
289
.macro DIV_FUNC_END name
 
290
        cfi_start       __\name, LSYM(Lend_div0)
 
291
LSYM(Ldiv0):
 
292
#ifdef __thumb__
 
293
        THUMB_LDIV0 \name
 
294
#else
 
295
        ARM_LDIV0 \name
 
296
#endif
 
297
        cfi_end LSYM(Lend_div0)
 
298
        FUNC_END \name
 
299
.endm
 
300
 
 
301
.macro THUMB_FUNC_START name
 
302
        .globl  SYM (\name)
 
303
        TYPE    (\name)
 
304
        .thumb_func
 
305
SYM (\name):
 
306
.endm
 
307
 
 
308
/* Function start macros.  Variants for ARM and Thumb.  */
 
309
 
 
310
#ifdef __thumb__
 
311
#define THUMB_FUNC .thumb_func
 
312
#define THUMB_CODE .force_thumb
 
313
# if defined(__thumb2__)
 
314
#define THUMB_SYNTAX .syntax divided
 
315
# else
 
316
#define THUMB_SYNTAX
 
317
# endif
 
318
#else
 
319
#define THUMB_FUNC
 
320
#define THUMB_CODE
 
321
#define THUMB_SYNTAX
 
322
#endif
 
323
 
 
324
.macro FUNC_START name
 
325
        .text
 
326
        .globl SYM (__\name)
 
327
        TYPE (__\name)
 
328
        .align 0
 
329
        THUMB_CODE
 
330
        THUMB_FUNC
 
331
        THUMB_SYNTAX
 
332
SYM (__\name):
 
333
.endm
 
334
 
 
335
/* Special function that will always be coded in ARM assembly, even if
 
336
   in Thumb-only compilation.  */
 
337
 
 
338
#if defined(__thumb2__)
 
339
 
 
340
/* For Thumb-2 we build everything in thumb mode.  */
 
341
.macro ARM_FUNC_START name
 
342
       FUNC_START \name
 
343
       .syntax unified
 
344
.endm
 
345
#define EQUIV .thumb_set
 
346
.macro  ARM_CALL name
 
347
        bl      __\name
 
348
.endm
 
349
 
 
350
#elif defined(__INTERWORKING_STUBS__)
 
351
 
 
352
.macro  ARM_FUNC_START name
 
353
        FUNC_START \name
 
354
        bx      pc
 
355
        nop
 
356
        .arm
 
357
/* A hook to tell gdb that we've switched to ARM mode.  Also used to call
 
358
   directly from other local arm routines.  */
 
359
_L__\name:              
 
360
.endm
 
361
#define EQUIV .thumb_set
 
362
/* Branch directly to a function declared with ARM_FUNC_START.
 
363
   Must be called in arm mode.  */
 
364
.macro  ARM_CALL name
 
365
        bl      _L__\name
 
366
.endm
 
367
 
 
368
#else /* !(__INTERWORKING_STUBS__ || __thumb2__) */
 
369
 
 
370
.macro  ARM_FUNC_START name
 
371
        .text
 
372
        .globl SYM (__\name)
 
373
        TYPE (__\name)
 
374
        .align 0
 
375
        .arm
 
376
SYM (__\name):
 
377
.endm
 
378
#define EQUIV .set
 
379
.macro  ARM_CALL name
 
380
        bl      __\name
 
381
.endm
 
382
 
 
383
#endif
 
384
 
 
385
.macro  FUNC_ALIAS new old
 
386
        .globl  SYM (__\new)
 
387
#if defined (__thumb__)
 
388
        .thumb_set      SYM (__\new), SYM (__\old)
 
389
#else
 
390
        .set    SYM (__\new), SYM (__\old)
 
391
#endif
 
392
.endm
 
393
 
 
394
.macro  ARM_FUNC_ALIAS new old
 
395
        .globl  SYM (__\new)
 
396
        EQUIV   SYM (__\new), SYM (__\old)
 
397
#if defined(__INTERWORKING_STUBS__)
 
398
        .set    SYM (_L__\new), SYM (_L__\old)
 
399
#endif
 
400
.endm
 
401
 
 
402
#ifdef __thumb__
 
403
/* Register aliases.  */
 
404
 
 
405
work            .req    r4      @ XXXX is this safe ?
 
406
dividend        .req    r0
 
407
divisor         .req    r1
 
408
overdone        .req    r2
 
409
result          .req    r2
 
410
curbit          .req    r3
 
411
#endif
 
412
#if 0
 
413
ip              .req    r12
 
414
sp              .req    r13
 
415
lr              .req    r14
 
416
pc              .req    r15
 
417
#endif
 
418
 
 
419
/* ------------------------------------------------------------------------ */
 
420
/*              Bodies of the division and modulo routines.                 */
 
421
/* ------------------------------------------------------------------------ */  
 
422
.macro ARM_DIV_BODY dividend, divisor, result, curbit
 
423
 
 
424
#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
 
425
 
 
426
        clz     \curbit, \dividend
 
427
        clz     \result, \divisor
 
428
        sub     \curbit, \result, \curbit
 
429
        rsbs    \curbit, \curbit, #31
 
430
        addne   \curbit, \curbit, \curbit, lsl #1
 
431
        mov     \result, #0
 
432
        addne   pc, pc, \curbit, lsl #2
 
433
        nop
 
434
        .set    shift, 32
 
435
        .rept   32
 
436
        .set    shift, shift - 1
 
437
        cmp     \dividend, \divisor, lsl #shift
 
438
        adc     \result, \result, \result
 
439
        subcs   \dividend, \dividend, \divisor, lsl #shift
 
440
        .endr
 
441
 
 
442
#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
 
443
#if __ARM_ARCH__ >= 5
 
444
 
 
445
        clz     \curbit, \divisor
 
446
        clz     \result, \dividend
 
447
        sub     \result, \curbit, \result
 
448
        mov     \curbit, #1
 
449
        mov     \divisor, \divisor, lsl \result
 
450
        mov     \curbit, \curbit, lsl \result
 
451
        mov     \result, #0
 
452
        
 
453
#else /* __ARM_ARCH__ < 5 */
 
454
 
 
455
        @ Initially shift the divisor left 3 bits if possible,
 
456
        @ set curbit accordingly.  This allows for curbit to be located
 
457
        @ at the left end of each 4-bit nibbles in the division loop
 
458
        @ to save one loop in most cases.
 
459
        tst     \divisor, #0xe0000000
 
460
        moveq   \divisor, \divisor, lsl #3
 
461
        moveq   \curbit, #8
 
462
        movne   \curbit, #1
 
463
 
 
464
        @ Unless the divisor is very big, shift it up in multiples of
 
465
        @ four bits, since this is the amount of unwinding in the main
 
466
        @ division loop.  Continue shifting until the divisor is 
 
467
        @ larger than the dividend.
 
468
1:      cmp     \divisor, #0x10000000
 
469
        cmplo   \divisor, \dividend
 
470
        movlo   \divisor, \divisor, lsl #4
 
471
        movlo   \curbit, \curbit, lsl #4
 
472
        blo     1b
 
473
 
 
474
        @ For very big divisors, we must shift it a bit at a time, or
 
475
        @ we will be in danger of overflowing.
 
476
1:      cmp     \divisor, #0x80000000
 
477
        cmplo   \divisor, \dividend
 
478
        movlo   \divisor, \divisor, lsl #1
 
479
        movlo   \curbit, \curbit, lsl #1
 
480
        blo     1b
 
481
 
 
482
        mov     \result, #0
 
483
 
 
484
#endif /* __ARM_ARCH__ < 5 */
 
485
 
 
486
        @ Division loop
 
487
1:      cmp     \dividend, \divisor
 
488
        subhs   \dividend, \dividend, \divisor
 
489
        orrhs   \result,   \result,   \curbit
 
490
        cmp     \dividend, \divisor,  lsr #1
 
491
        subhs   \dividend, \dividend, \divisor, lsr #1
 
492
        orrhs   \result,   \result,   \curbit,  lsr #1
 
493
        cmp     \dividend, \divisor,  lsr #2
 
494
        subhs   \dividend, \dividend, \divisor, lsr #2
 
495
        orrhs   \result,   \result,   \curbit,  lsr #2
 
496
        cmp     \dividend, \divisor,  lsr #3
 
497
        subhs   \dividend, \dividend, \divisor, lsr #3
 
498
        orrhs   \result,   \result,   \curbit,  lsr #3
 
499
        cmp     \dividend, #0                   @ Early termination?
 
500
        movnes  \curbit,   \curbit,  lsr #4     @ No, any more bits to do?
 
501
        movne   \divisor,  \divisor, lsr #4
 
502
        bne     1b
 
503
 
 
504
#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
 
505
 
 
506
.endm
 
507
/* ------------------------------------------------------------------------ */  
 
508
.macro ARM_DIV2_ORDER divisor, order
 
509
 
 
510
#if __ARM_ARCH__ >= 5
 
511
 
 
512
        clz     \order, \divisor
 
513
        rsb     \order, \order, #31
 
514
 
 
515
#else
 
516
 
 
517
        cmp     \divisor, #(1 << 16)
 
518
        movhs   \divisor, \divisor, lsr #16
 
519
        movhs   \order, #16
 
520
        movlo   \order, #0
 
521
 
 
522
        cmp     \divisor, #(1 << 8)
 
523
        movhs   \divisor, \divisor, lsr #8
 
524
        addhs   \order, \order, #8
 
525
 
 
526
        cmp     \divisor, #(1 << 4)
 
527
        movhs   \divisor, \divisor, lsr #4
 
528
        addhs   \order, \order, #4
 
529
 
 
530
        cmp     \divisor, #(1 << 2)
 
531
        addhi   \order, \order, #3
 
532
        addls   \order, \order, \divisor, lsr #1
 
533
 
 
534
#endif
 
535
 
 
536
.endm
 
537
/* ------------------------------------------------------------------------ */
 
538
.macro ARM_MOD_BODY dividend, divisor, order, spare
 
539
 
 
540
#if __ARM_ARCH__ >= 5 && ! defined (__OPTIMIZE_SIZE__)
 
541
 
 
542
        clz     \order, \divisor
 
543
        clz     \spare, \dividend
 
544
        sub     \order, \order, \spare
 
545
        rsbs    \order, \order, #31
 
546
        addne   pc, pc, \order, lsl #3
 
547
        nop
 
548
        .set    shift, 32
 
549
        .rept   32
 
550
        .set    shift, shift - 1
 
551
        cmp     \dividend, \divisor, lsl #shift
 
552
        subcs   \dividend, \dividend, \divisor, lsl #shift
 
553
        .endr
 
554
 
 
555
#else /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
 
556
#if __ARM_ARCH__ >= 5
 
557
 
 
558
        clz     \order, \divisor
 
559
        clz     \spare, \dividend
 
560
        sub     \order, \order, \spare
 
561
        mov     \divisor, \divisor, lsl \order
 
562
        
 
563
#else /* __ARM_ARCH__ < 5 */
 
564
 
 
565
        mov     \order, #0
 
566
 
 
567
        @ Unless the divisor is very big, shift it up in multiples of
 
568
        @ four bits, since this is the amount of unwinding in the main
 
569
        @ division loop.  Continue shifting until the divisor is 
 
570
        @ larger than the dividend.
 
571
1:      cmp     \divisor, #0x10000000
 
572
        cmplo   \divisor, \dividend
 
573
        movlo   \divisor, \divisor, lsl #4
 
574
        addlo   \order, \order, #4
 
575
        blo     1b
 
576
 
 
577
        @ For very big divisors, we must shift it a bit at a time, or
 
578
        @ we will be in danger of overflowing.
 
579
1:      cmp     \divisor, #0x80000000
 
580
        cmplo   \divisor, \dividend
 
581
        movlo   \divisor, \divisor, lsl #1
 
582
        addlo   \order, \order, #1
 
583
        blo     1b
 
584
 
 
585
#endif /* __ARM_ARCH__ < 5 */
 
586
 
 
587
        @ Perform all needed substractions to keep only the reminder.
 
588
        @ Do comparisons in batch of 4 first.
 
589
        subs    \order, \order, #3              @ yes, 3 is intended here
 
590
        blt     2f
 
591
 
 
592
1:      cmp     \dividend, \divisor
 
593
        subhs   \dividend, \dividend, \divisor
 
594
        cmp     \dividend, \divisor,  lsr #1
 
595
        subhs   \dividend, \dividend, \divisor, lsr #1
 
596
        cmp     \dividend, \divisor,  lsr #2
 
597
        subhs   \dividend, \dividend, \divisor, lsr #2
 
598
        cmp     \dividend, \divisor,  lsr #3
 
599
        subhs   \dividend, \dividend, \divisor, lsr #3
 
600
        cmp     \dividend, #1
 
601
        mov     \divisor, \divisor, lsr #4
 
602
        subges  \order, \order, #4
 
603
        bge     1b
 
604
 
 
605
        tst     \order, #3
 
606
        teqne   \dividend, #0
 
607
        beq     5f
 
608
 
 
609
        @ Either 1, 2 or 3 comparison/substractions are left.
 
610
2:      cmn     \order, #2
 
611
        blt     4f
 
612
        beq     3f
 
613
        cmp     \dividend, \divisor
 
614
        subhs   \dividend, \dividend, \divisor
 
615
        mov     \divisor,  \divisor,  lsr #1
 
616
3:      cmp     \dividend, \divisor
 
617
        subhs   \dividend, \dividend, \divisor
 
618
        mov     \divisor,  \divisor,  lsr #1
 
619
4:      cmp     \dividend, \divisor
 
620
        subhs   \dividend, \dividend, \divisor
 
621
5:
 
622
 
 
623
#endif /* __ARM_ARCH__ < 5 || defined (__OPTIMIZE_SIZE__) */
 
624
 
 
625
.endm
 
626
/* ------------------------------------------------------------------------ */
 
627
.macro THUMB_DIV_MOD_BODY modulo
 
628
        @ Load the constant 0x10000000 into our work register.
 
629
        mov     work, #1
 
630
        lsl     work, #28
 
631
LSYM(Loop1):
 
632
        @ Unless the divisor is very big, shift it up in multiples of
 
633
        @ four bits, since this is the amount of unwinding in the main
 
634
        @ division loop.  Continue shifting until the divisor is 
 
635
        @ larger than the dividend.
 
636
        cmp     divisor, work
 
637
        bhs     LSYM(Lbignum)
 
638
        cmp     divisor, dividend
 
639
        bhs     LSYM(Lbignum)
 
640
        lsl     divisor, #4
 
641
        lsl     curbit,  #4
 
642
        b       LSYM(Loop1)
 
643
LSYM(Lbignum):
 
644
        @ Set work to 0x80000000
 
645
        lsl     work, #3
 
646
LSYM(Loop2):
 
647
        @ For very big divisors, we must shift it a bit at a time, or
 
648
        @ we will be in danger of overflowing.
 
649
        cmp     divisor, work
 
650
        bhs     LSYM(Loop3)
 
651
        cmp     divisor, dividend
 
652
        bhs     LSYM(Loop3)
 
653
        lsl     divisor, #1
 
654
        lsl     curbit,  #1
 
655
        b       LSYM(Loop2)
 
656
LSYM(Loop3):
 
657
        @ Test for possible subtractions ...
 
658
  .if \modulo
 
659
        @ ... On the final pass, this may subtract too much from the dividend, 
 
660
        @ so keep track of which subtractions are done, we can fix them up 
 
661
        @ afterwards.
 
662
        mov     overdone, #0
 
663
        cmp     dividend, divisor
 
664
        blo     LSYM(Lover1)
 
665
        sub     dividend, dividend, divisor
 
666
LSYM(Lover1):
 
667
        lsr     work, divisor, #1
 
668
        cmp     dividend, work
 
669
        blo     LSYM(Lover2)
 
670
        sub     dividend, dividend, work
 
671
        mov     ip, curbit
 
672
        mov     work, #1
 
673
        ror     curbit, work
 
674
        orr     overdone, curbit
 
675
        mov     curbit, ip
 
676
LSYM(Lover2):
 
677
        lsr     work, divisor, #2
 
678
        cmp     dividend, work
 
679
        blo     LSYM(Lover3)
 
680
        sub     dividend, dividend, work
 
681
        mov     ip, curbit
 
682
        mov     work, #2
 
683
        ror     curbit, work
 
684
        orr     overdone, curbit
 
685
        mov     curbit, ip
 
686
LSYM(Lover3):
 
687
        lsr     work, divisor, #3
 
688
        cmp     dividend, work
 
689
        blo     LSYM(Lover4)
 
690
        sub     dividend, dividend, work
 
691
        mov     ip, curbit
 
692
        mov     work, #3
 
693
        ror     curbit, work
 
694
        orr     overdone, curbit
 
695
        mov     curbit, ip
 
696
LSYM(Lover4):
 
697
        mov     ip, curbit
 
698
  .else
 
699
        @ ... and note which bits are done in the result.  On the final pass,
 
700
        @ this may subtract too much from the dividend, but the result will be ok,
 
701
        @ since the "bit" will have been shifted out at the bottom.
 
702
        cmp     dividend, divisor
 
703
        blo     LSYM(Lover1)
 
704
        sub     dividend, dividend, divisor
 
705
        orr     result, result, curbit
 
706
LSYM(Lover1):
 
707
        lsr     work, divisor, #1
 
708
        cmp     dividend, work
 
709
        blo     LSYM(Lover2)
 
710
        sub     dividend, dividend, work
 
711
        lsr     work, curbit, #1
 
712
        orr     result, work
 
713
LSYM(Lover2):
 
714
        lsr     work, divisor, #2
 
715
        cmp     dividend, work
 
716
        blo     LSYM(Lover3)
 
717
        sub     dividend, dividend, work
 
718
        lsr     work, curbit, #2
 
719
        orr     result, work
 
720
LSYM(Lover3):
 
721
        lsr     work, divisor, #3
 
722
        cmp     dividend, work
 
723
        blo     LSYM(Lover4)
 
724
        sub     dividend, dividend, work
 
725
        lsr     work, curbit, #3
 
726
        orr     result, work
 
727
LSYM(Lover4):
 
728
  .endif
 
729
        
 
730
        cmp     dividend, #0                    @ Early termination?
 
731
        beq     LSYM(Lover5)
 
732
        lsr     curbit,  #4                     @ No, any more bits to do?
 
733
        beq     LSYM(Lover5)
 
734
        lsr     divisor, #4
 
735
        b       LSYM(Loop3)
 
736
LSYM(Lover5):
 
737
  .if \modulo
 
738
        @ Any subtractions that we should not have done will be recorded in
 
739
        @ the top three bits of "overdone".  Exactly which were not needed
 
740
        @ are governed by the position of the bit, stored in ip.
 
741
        mov     work, #0xe
 
742
        lsl     work, #28
 
743
        and     overdone, work
 
744
        beq     LSYM(Lgot_result)
 
745
        
 
746
        @ If we terminated early, because dividend became zero, then the 
 
747
        @ bit in ip will not be in the bottom nibble, and we should not
 
748
        @ perform the additions below.  We must test for this though
 
749
        @ (rather relying upon the TSTs to prevent the additions) since
 
750
        @ the bit in ip could be in the top two bits which might then match
 
751
        @ with one of the smaller RORs.
 
752
        mov     curbit, ip
 
753
        mov     work, #0x7
 
754
        tst     curbit, work
 
755
        beq     LSYM(Lgot_result)
 
756
        
 
757
        mov     curbit, ip
 
758
        mov     work, #3
 
759
        ror     curbit, work
 
760
        tst     overdone, curbit
 
761
        beq     LSYM(Lover6)
 
762
        lsr     work, divisor, #3
 
763
        add     dividend, work
 
764
LSYM(Lover6):
 
765
        mov     curbit, ip
 
766
        mov     work, #2
 
767
        ror     curbit, work
 
768
        tst     overdone, curbit
 
769
        beq     LSYM(Lover7)
 
770
        lsr     work, divisor, #2
 
771
        add     dividend, work
 
772
LSYM(Lover7):
 
773
        mov     curbit, ip
 
774
        mov     work, #1
 
775
        ror     curbit, work
 
776
        tst     overdone, curbit
 
777
        beq     LSYM(Lgot_result)
 
778
        lsr     work, divisor, #1
 
779
        add     dividend, work
 
780
  .endif
 
781
LSYM(Lgot_result):
 
782
.endm   
 
783
/* ------------------------------------------------------------------------ */
 
784
/*              Start of the Real Functions                                 */
 
785
/* ------------------------------------------------------------------------ */
 
786
#ifdef L_udivsi3
 
787
 
 
788
        FUNC_START udivsi3
 
789
        FUNC_ALIAS aeabi_uidiv udivsi3
 
790
 
 
791
#ifdef __thumb__
 
792
 
 
793
        cmp     divisor, #0
 
794
        beq     LSYM(Ldiv0)
 
795
        mov     curbit, #1
 
796
        mov     result, #0
 
797
        
 
798
        push    { work }
 
799
        cmp     dividend, divisor
 
800
        blo     LSYM(Lgot_result)
 
801
 
 
802
        THUMB_DIV_MOD_BODY 0
 
803
        
 
804
        mov     r0, result
 
805
        pop     { work }
 
806
        RET
 
807
 
 
808
#else /* ARM version.  */
 
809
 
 
810
        subs    r2, r1, #1
 
811
        RETc(eq)
 
812
        bcc     LSYM(Ldiv0)
 
813
        cmp     r0, r1
 
814
        bls     11f
 
815
        tst     r1, r2
 
816
        beq     12f
 
817
        
 
818
        ARM_DIV_BODY r0, r1, r2, r3
 
819
        
 
820
        mov     r0, r2
 
821
        RET     
 
822
 
 
823
11:     moveq   r0, #1
 
824
        movne   r0, #0
 
825
        RET
 
826
 
 
827
12:     ARM_DIV2_ORDER r1, r2
 
828
 
 
829
        mov     r0, r0, lsr r2
 
830
        RET
 
831
 
 
832
#endif /* ARM version */
 
833
 
 
834
        DIV_FUNC_END udivsi3
 
835
 
 
836
FUNC_START aeabi_uidivmod
 
837
#ifdef __thumb__
 
838
        push    {r0, r1, lr}
 
839
        bl      SYM(__udivsi3)
 
840
        POP     {r1, r2, r3}
 
841
        mul     r2, r0
 
842
        sub     r1, r1, r2
 
843
        bx      r3
 
844
#else
 
845
        stmfd   sp!, { r0, r1, lr }
 
846
        bl      SYM(__udivsi3)
 
847
        ldmfd   sp!, { r1, r2, lr }
 
848
        mul     r3, r2, r0
 
849
        sub     r1, r1, r3
 
850
        RET
 
851
#endif
 
852
        FUNC_END aeabi_uidivmod
 
853
        
 
854
#endif /* L_udivsi3 */
 
855
/* ------------------------------------------------------------------------ */
 
856
#ifdef L_umodsi3
 
857
 
 
858
        FUNC_START umodsi3
 
859
 
 
860
#ifdef __thumb__
 
861
 
 
862
        cmp     divisor, #0
 
863
        beq     LSYM(Ldiv0)
 
864
        mov     curbit, #1
 
865
        cmp     dividend, divisor
 
866
        bhs     LSYM(Lover10)
 
867
        RET     
 
868
 
 
869
LSYM(Lover10):
 
870
        push    { work }
 
871
 
 
872
        THUMB_DIV_MOD_BODY 1
 
873
        
 
874
        pop     { work }
 
875
        RET
 
876
        
 
877
#else  /* ARM version.  */
 
878
        
 
879
        subs    r2, r1, #1                      @ compare divisor with 1
 
880
        bcc     LSYM(Ldiv0)
 
881
        cmpne   r0, r1                          @ compare dividend with divisor
 
882
        moveq   r0, #0
 
883
        tsthi   r1, r2                          @ see if divisor is power of 2
 
884
        andeq   r0, r0, r2
 
885
        RETc(ls)
 
886
 
 
887
        ARM_MOD_BODY r0, r1, r2, r3
 
888
        
 
889
        RET     
 
890
 
 
891
#endif /* ARM version.  */
 
892
        
 
893
        DIV_FUNC_END umodsi3
 
894
 
 
895
#endif /* L_umodsi3 */
 
896
/* ------------------------------------------------------------------------ */
 
897
#ifdef L_divsi3
 
898
 
 
899
        FUNC_START divsi3       
 
900
        FUNC_ALIAS aeabi_idiv divsi3
 
901
 
 
902
#ifdef __thumb__
 
903
        cmp     divisor, #0
 
904
        beq     LSYM(Ldiv0)
 
905
        
 
906
        push    { work }
 
907
        mov     work, dividend
 
908
        eor     work, divisor           @ Save the sign of the result.
 
909
        mov     ip, work
 
910
        mov     curbit, #1
 
911
        mov     result, #0
 
912
        cmp     divisor, #0
 
913
        bpl     LSYM(Lover10)
 
914
        neg     divisor, divisor        @ Loops below use unsigned.
 
915
LSYM(Lover10):
 
916
        cmp     dividend, #0
 
917
        bpl     LSYM(Lover11)
 
918
        neg     dividend, dividend
 
919
LSYM(Lover11):
 
920
        cmp     dividend, divisor
 
921
        blo     LSYM(Lgot_result)
 
922
 
 
923
        THUMB_DIV_MOD_BODY 0
 
924
        
 
925
        mov     r0, result
 
926
        mov     work, ip
 
927
        cmp     work, #0
 
928
        bpl     LSYM(Lover12)
 
929
        neg     r0, r0
 
930
LSYM(Lover12):
 
931
        pop     { work }
 
932
        RET
 
933
 
 
934
#else /* ARM version.  */
 
935
        
 
936
        cmp     r1, #0
 
937
        eor     ip, r0, r1                      @ save the sign of the result.
 
938
        beq     LSYM(Ldiv0)
 
939
        rsbmi   r1, r1, #0                      @ loops below use unsigned.
 
940
        subs    r2, r1, #1                      @ division by 1 or -1 ?
 
941
        beq     10f
 
942
        movs    r3, r0
 
943
        rsbmi   r3, r0, #0                      @ positive dividend value
 
944
        cmp     r3, r1
 
945
        bls     11f
 
946
        tst     r1, r2                          @ divisor is power of 2 ?
 
947
        beq     12f
 
948
 
 
949
        ARM_DIV_BODY r3, r1, r0, r2
 
950
        
 
951
        cmp     ip, #0
 
952
        rsbmi   r0, r0, #0
 
953
        RET     
 
954
 
 
955
10:     teq     ip, r0                          @ same sign ?
 
956
        rsbmi   r0, r0, #0
 
957
        RET     
 
958
 
 
959
11:     movlo   r0, #0
 
960
        moveq   r0, ip, asr #31
 
961
        orreq   r0, r0, #1
 
962
        RET
 
963
 
 
964
12:     ARM_DIV2_ORDER r1, r2
 
965
 
 
966
        cmp     ip, #0
 
967
        mov     r0, r3, lsr r2
 
968
        rsbmi   r0, r0, #0
 
969
        RET
 
970
 
 
971
#endif /* ARM version */
 
972
        
 
973
        DIV_FUNC_END divsi3
 
974
 
 
975
FUNC_START aeabi_idivmod
 
976
#ifdef __thumb__
 
977
        push    {r0, r1, lr}
 
978
        bl      SYM(__divsi3)
 
979
        POP     {r1, r2, r3}
 
980
        mul     r2, r0
 
981
        sub     r1, r1, r2
 
982
        bx      r3
 
983
#else
 
984
        stmfd   sp!, { r0, r1, lr }
 
985
        bl      SYM(__divsi3)
 
986
        ldmfd   sp!, { r1, r2, lr }
 
987
        mul     r3, r2, r0
 
988
        sub     r1, r1, r3
 
989
        RET
 
990
#endif
 
991
        FUNC_END aeabi_idivmod
 
992
        
 
993
#endif /* L_divsi3 */
 
994
/* ------------------------------------------------------------------------ */
 
995
#ifdef L_modsi3
 
996
 
 
997
        FUNC_START modsi3
 
998
 
 
999
#ifdef __thumb__
 
1000
 
 
1001
        mov     curbit, #1
 
1002
        cmp     divisor, #0
 
1003
        beq     LSYM(Ldiv0)
 
1004
        bpl     LSYM(Lover10)
 
1005
        neg     divisor, divisor                @ Loops below use unsigned.
 
1006
LSYM(Lover10):
 
1007
        push    { work }
 
1008
        @ Need to save the sign of the dividend, unfortunately, we need
 
1009
        @ work later on.  Must do this after saving the original value of
 
1010
        @ the work register, because we will pop this value off first.
 
1011
        push    { dividend }
 
1012
        cmp     dividend, #0
 
1013
        bpl     LSYM(Lover11)
 
1014
        neg     dividend, dividend
 
1015
LSYM(Lover11):
 
1016
        cmp     dividend, divisor
 
1017
        blo     LSYM(Lgot_result)
 
1018
 
 
1019
        THUMB_DIV_MOD_BODY 1
 
1020
                
 
1021
        pop     { work }
 
1022
        cmp     work, #0
 
1023
        bpl     LSYM(Lover12)
 
1024
        neg     dividend, dividend
 
1025
LSYM(Lover12):
 
1026
        pop     { work }
 
1027
        RET     
 
1028
 
 
1029
#else /* ARM version.  */
 
1030
        
 
1031
        cmp     r1, #0
 
1032
        beq     LSYM(Ldiv0)
 
1033
        rsbmi   r1, r1, #0                      @ loops below use unsigned.
 
1034
        movs    ip, r0                          @ preserve sign of dividend
 
1035
        rsbmi   r0, r0, #0                      @ if negative make positive
 
1036
        subs    r2, r1, #1                      @ compare divisor with 1
 
1037
        cmpne   r0, r1                          @ compare dividend with divisor
 
1038
        moveq   r0, #0
 
1039
        tsthi   r1, r2                          @ see if divisor is power of 2
 
1040
        andeq   r0, r0, r2
 
1041
        bls     10f
 
1042
 
 
1043
        ARM_MOD_BODY r0, r1, r2, r3
 
1044
 
 
1045
10:     cmp     ip, #0
 
1046
        rsbmi   r0, r0, #0
 
1047
        RET     
 
1048
 
 
1049
#endif /* ARM version */
 
1050
        
 
1051
        DIV_FUNC_END modsi3
 
1052
 
 
1053
#endif /* L_modsi3 */
 
1054
/* ------------------------------------------------------------------------ */
 
1055
#ifdef L_dvmd_tls
 
1056
 
 
1057
        FUNC_START div0
 
1058
        FUNC_ALIAS aeabi_idiv0 div0
 
1059
        FUNC_ALIAS aeabi_ldiv0 div0
 
1060
 
 
1061
        RET
 
1062
 
 
1063
        FUNC_END aeabi_ldiv0
 
1064
        FUNC_END aeabi_idiv0
 
1065
        FUNC_END div0
 
1066
        
 
1067
#endif /* L_divmodsi_tools */
 
1068
/* ------------------------------------------------------------------------ */
 
1069
#ifdef L_dvmd_lnx
 
1070
@ GNU/Linux division-by zero handler.  Used in place of L_dvmd_tls
 
1071
 
 
1072
/* Constant taken from <asm/signal.h>.  */
 
1073
#define SIGFPE  8
 
1074
 
 
1075
        ARM_FUNC_START div0
 
1076
 
 
1077
        do_push {r1, lr}
 
1078
        mov     r0, #SIGFPE
 
1079
        bl      SYM(raise) __PLT__
 
1080
        RETLDM  r1
 
1081
 
 
1082
        FUNC_END div0
 
1083
        
 
1084
#endif /* L_dvmd_lnx */
 
1085
/* ------------------------------------------------------------------------ */
 
1086
/* Dword shift operations.  */
 
1087
/* All the following Dword shift variants rely on the fact that
 
1088
        shft xxx, Reg
 
1089
   is in fact done as
 
1090
        shft xxx, (Reg & 255)
 
1091
   so for Reg value in (32...63) and (-1...-31) we will get zero (in the
 
1092
   case of logical shifts) or the sign (for asr).  */
 
1093
 
 
1094
#ifdef __ARMEB__
 
1095
#define al      r1
 
1096
#define ah      r0
 
1097
#else
 
1098
#define al      r0
 
1099
#define ah      r1
 
1100
#endif
 
1101
 
 
1102
/* Prevent __aeabi double-word shifts from being produced on SymbianOS.  */
 
1103
#ifndef __symbian__
 
1104
 
 
1105
#ifdef L_lshrdi3
 
1106
 
 
1107
        FUNC_START lshrdi3
 
1108
        FUNC_ALIAS aeabi_llsr lshrdi3
 
1109
        
 
1110
#ifdef __thumb__
 
1111
        lsr     al, r2
 
1112
        mov     r3, ah
 
1113
        lsr     ah, r2
 
1114
        mov     ip, r3
 
1115
        sub     r2, #32
 
1116
        lsr     r3, r2
 
1117
        orr     al, r3
 
1118
        neg     r2, r2
 
1119
        mov     r3, ip
 
1120
        lsl     r3, r2
 
1121
        orr     al, r3
 
1122
        RET
 
1123
#else
 
1124
        subs    r3, r2, #32
 
1125
        rsb     ip, r2, #32
 
1126
        movmi   al, al, lsr r2
 
1127
        movpl   al, ah, lsr r3
 
1128
        orrmi   al, al, ah, lsl ip
 
1129
        mov     ah, ah, lsr r2
 
1130
        RET
 
1131
#endif
 
1132
        FUNC_END aeabi_llsr
 
1133
        FUNC_END lshrdi3
 
1134
 
 
1135
#endif
 
1136
        
 
1137
#ifdef L_ashrdi3
 
1138
        
 
1139
        FUNC_START ashrdi3
 
1140
        FUNC_ALIAS aeabi_lasr ashrdi3
 
1141
        
 
1142
#ifdef __thumb__
 
1143
        lsr     al, r2
 
1144
        mov     r3, ah
 
1145
        asr     ah, r2
 
1146
        sub     r2, #32
 
1147
        @ If r2 is negative at this point the following step would OR
 
1148
        @ the sign bit into all of AL.  That's not what we want...
 
1149
        bmi     1f
 
1150
        mov     ip, r3
 
1151
        asr     r3, r2
 
1152
        orr     al, r3
 
1153
        mov     r3, ip
 
1154
1:
 
1155
        neg     r2, r2
 
1156
        lsl     r3, r2
 
1157
        orr     al, r3
 
1158
        RET
 
1159
#else
 
1160
        subs    r3, r2, #32
 
1161
        rsb     ip, r2, #32
 
1162
        movmi   al, al, lsr r2
 
1163
        movpl   al, ah, asr r3
 
1164
        orrmi   al, al, ah, lsl ip
 
1165
        mov     ah, ah, asr r2
 
1166
        RET
 
1167
#endif
 
1168
 
 
1169
        FUNC_END aeabi_lasr
 
1170
        FUNC_END ashrdi3
 
1171
 
 
1172
#endif
 
1173
 
 
1174
#ifdef L_ashldi3
 
1175
 
 
1176
        FUNC_START ashldi3
 
1177
        FUNC_ALIAS aeabi_llsl ashldi3
 
1178
        
 
1179
#ifdef __thumb__
 
1180
        lsl     ah, r2
 
1181
        mov     r3, al
 
1182
        lsl     al, r2
 
1183
        mov     ip, r3
 
1184
        sub     r2, #32
 
1185
        lsl     r3, r2
 
1186
        orr     ah, r3
 
1187
        neg     r2, r2
 
1188
        mov     r3, ip
 
1189
        lsr     r3, r2
 
1190
        orr     ah, r3
 
1191
        RET
 
1192
#else
 
1193
        subs    r3, r2, #32
 
1194
        rsb     ip, r2, #32
 
1195
        movmi   ah, ah, lsl r2
 
1196
        movpl   ah, al, lsl r3
 
1197
        orrmi   ah, ah, al, lsr ip
 
1198
        mov     al, al, lsl r2
 
1199
        RET
 
1200
#endif
 
1201
        FUNC_END aeabi_llsl
 
1202
        FUNC_END ashldi3
 
1203
 
 
1204
#endif
 
1205
 
 
1206
#endif /* __symbian__ */
 
1207
 
 
1208
/* ------------------------------------------------------------------------ */
 
1209
/* These next two sections are here despite the fact that they contain Thumb 
 
1210
   assembler because their presence allows interworked code to be linked even
 
1211
   when the GCC library is this one.  */
 
1212
                
 
1213
/* Do not build the interworking functions when the target architecture does 
 
1214
   not support Thumb instructions.  (This can be a multilib option).  */
 
1215
#if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__\
 
1216
      || defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__ \
 
1217
      || __ARM_ARCH__ >= 6
 
1218
 
 
1219
#if defined L_call_via_rX
 
1220
 
 
1221
/* These labels & instructions are used by the Arm/Thumb interworking code. 
 
1222
   The address of function to be called is loaded into a register and then 
 
1223
   one of these labels is called via a BL instruction.  This puts the 
 
1224
   return address into the link register with the bottom bit set, and the 
 
1225
   code here switches to the correct mode before executing the function.  */
 
1226
        
 
1227
        .text
 
1228
        .align 0
 
1229
        .force_thumb
 
1230
 
 
1231
.macro call_via register
 
1232
        THUMB_FUNC_START _call_via_\register
 
1233
 
 
1234
        bx      \register
 
1235
        nop
 
1236
 
 
1237
        SIZE    (_call_via_\register)
 
1238
.endm
 
1239
 
 
1240
        call_via r0
 
1241
        call_via r1
 
1242
        call_via r2
 
1243
        call_via r3
 
1244
        call_via r4
 
1245
        call_via r5
 
1246
        call_via r6
 
1247
        call_via r7
 
1248
        call_via r8
 
1249
        call_via r9
 
1250
        call_via sl
 
1251
        call_via fp
 
1252
        call_via ip
 
1253
        call_via sp
 
1254
        call_via lr
 
1255
 
 
1256
#endif /* L_call_via_rX */
 
1257
 
 
1258
/* Don't bother with the old interworking routines for Thumb-2.  */
 
1259
/* ??? Maybe only omit these on v7m.  */
 
1260
#ifndef __thumb2__
 
1261
 
 
1262
#if defined L_interwork_call_via_rX
 
1263
 
 
1264
/* These labels & instructions are used by the Arm/Thumb interworking code,
 
1265
   when the target address is in an unknown instruction set.  The address 
 
1266
   of function to be called is loaded into a register and then one of these
 
1267
   labels is called via a BL instruction.  This puts the return address 
 
1268
   into the link register with the bottom bit set, and the code here 
 
1269
   switches to the correct mode before executing the function.  Unfortunately
 
1270
   the target code cannot be relied upon to return via a BX instruction, so
 
1271
   instead we have to store the resturn address on the stack and allow the
 
1272
   called function to return here instead.  Upon return we recover the real
 
1273
   return address and use a BX to get back to Thumb mode.
 
1274
 
 
1275
   There are three variations of this code.  The first,
 
1276
   _interwork_call_via_rN(), will push the return address onto the
 
1277
   stack and pop it in _arm_return().  It should only be used if all
 
1278
   arguments are passed in registers.
 
1279
 
 
1280
   The second, _interwork_r7_call_via_rN(), instead stores the return
 
1281
   address at [r7, #-4].  It is the caller's responsibility to ensure
 
1282
   that this address is valid and contains no useful data.
 
1283
 
 
1284
   The third, _interwork_r11_call_via_rN(), works in the same way but
 
1285
   uses r11 instead of r7.  It is useful if the caller does not really
 
1286
   need a frame pointer.  */
 
1287
        
 
1288
        .text
 
1289
        .align 0
 
1290
 
 
1291
        .code   32
 
1292
        .globl _arm_return
 
1293
LSYM(Lstart_arm_return):
 
1294
        cfi_start       LSYM(Lstart_arm_return) LSYM(Lend_arm_return)
 
1295
        cfi_push        0, 0xe, -0x8, 0x8
 
1296
        nop     @ This nop is for the benefit of debuggers, so that
 
1297
                @ backtraces will use the correct unwind information.
 
1298
_arm_return:
 
1299
        RETLDM  unwind=LSYM(Lstart_arm_return)
 
1300
        cfi_end LSYM(Lend_arm_return)
 
1301
 
 
1302
        .globl _arm_return_r7
 
1303
_arm_return_r7:
 
1304
        ldr     lr, [r7, #-4]
 
1305
        bx      lr
 
1306
 
 
1307
        .globl _arm_return_r11
 
1308
_arm_return_r11:
 
1309
        ldr     lr, [r11, #-4]
 
1310
        bx      lr
 
1311
 
 
1312
.macro interwork_with_frame frame, register, name, return
 
1313
        .code   16
 
1314
 
 
1315
        THUMB_FUNC_START \name
 
1316
 
 
1317
        bx      pc
 
1318
        nop
 
1319
 
 
1320
        .code   32
 
1321
        tst     \register, #1
 
1322
        streq   lr, [\frame, #-4]
 
1323
        adreq   lr, _arm_return_\frame
 
1324
        bx      \register
 
1325
 
 
1326
        SIZE    (\name)
 
1327
.endm
 
1328
 
 
1329
.macro interwork register
 
1330
        .code   16
 
1331
 
 
1332
        THUMB_FUNC_START _interwork_call_via_\register
 
1333
 
 
1334
        bx      pc
 
1335
        nop
 
1336
 
 
1337
        .code   32
 
1338
        .globl LSYM(Lchange_\register)
 
1339
LSYM(Lchange_\register):
 
1340
        tst     \register, #1
 
1341
        streq   lr, [sp, #-8]!
 
1342
        adreq   lr, _arm_return
 
1343
        bx      \register
 
1344
 
 
1345
        SIZE    (_interwork_call_via_\register)
 
1346
 
 
1347
        interwork_with_frame r7,\register,_interwork_r7_call_via_\register
 
1348
        interwork_with_frame r11,\register,_interwork_r11_call_via_\register
 
1349
.endm
 
1350
        
 
1351
        interwork r0
 
1352
        interwork r1
 
1353
        interwork r2
 
1354
        interwork r3
 
1355
        interwork r4
 
1356
        interwork r5
 
1357
        interwork r6
 
1358
        interwork r7
 
1359
        interwork r8
 
1360
        interwork r9
 
1361
        interwork sl
 
1362
        interwork fp
 
1363
        interwork ip
 
1364
        interwork sp
 
1365
        
 
1366
        /* The LR case has to be handled a little differently...  */
 
1367
        .code 16
 
1368
 
 
1369
        THUMB_FUNC_START _interwork_call_via_lr
 
1370
 
 
1371
        bx      pc
 
1372
        nop
 
1373
        
 
1374
        .code 32
 
1375
        .globl .Lchange_lr
 
1376
.Lchange_lr:
 
1377
        tst     lr, #1
 
1378
        stmeqdb r13!, {lr, pc}
 
1379
        mov     ip, lr
 
1380
        adreq   lr, _arm_return
 
1381
        bx      ip
 
1382
        
 
1383
        SIZE    (_interwork_call_via_lr)
 
1384
        
 
1385
#endif /* L_interwork_call_via_rX */
 
1386
#endif /* !__thumb2__ */
 
1387
#endif /* Arch supports thumb.  */
 
1388
 
 
1389
#ifndef __symbian__
 
1390
//#include "ieee754-df.S"
 
1391
//#include "ieee754-sf.S"
 
1392
#include "bpabi.S"
 
1393
#endif /* __symbian__ */