~ubuntu-branches/ubuntu/lucid/fpc/lucid-proposed

« back to all changes in this revision

Viewing changes to fpcsrc/rtl/arm/arm.inc

  • Committer: Bazaar Package Importer
  • Author(s): Mazen Neifer, Torsten Werner, Mazen Neifer
  • Date: 2008-10-09 23:29:00 UTC
  • mfrom: (4.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20081009232900-553f61m37jkp6upv
Tags: 2.2.2-4
[ Torsten Werner ]
* Update ABI version in fpc-depends automatically.
* Remove empty directories from binary package fpc-source.

[ Mazen Neifer ]
* Removed leading path when calling update-alternatives to remove a Linitian
  error.
* Fixed clean target.
* Improved description of packages. (Closes: #498882)

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
{$asmmode gas}
19
19
 
 
20
{$ifndef FPC_SYSTEM_HAS_MOVE}
 
21
{$define FPC_SYSTEM_FPC_MOVE}
 
22
{$endif FPC_SYSTEM_HAS_MOVE}
 
23
 
 
24
{$ifdef FPC_SYSTEM_FPC_MOVE}
20
25
const
21
26
  cpu_has_edsp : boolean = false;
22
27
  in_edsp_test : boolean = false;
 
28
{$endif FPC_SYSTEM_FPC_MOVE}
23
29
 
24
 
procedure fpc_cpuinit;
25
 
begin
26
30
{$if not(defined(wince)) and not(defined(gba)) and not(defined(nds)) and not(defined(FPUSOFT)) and not(defined(FPULIBGCC))}
 
31
{$define FPC_SYSTEM_HAS_SYSINITFPU}
 
32
Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
 
33
begin
27
34
  { Enable FPU exceptions, but disable INEXACT, UNDERFLOW, DENORMAL }
28
35
  asm
29
36
    rfs r0
31
38
    orr r0,r0,#0x00070000
32
39
    wfs r0
33
40
  end;
 
41
end;
34
42
{$endif}
 
43
 
 
44
procedure fpc_cpuinit;
 
45
begin
 
46
  SysInitFPU;
35
47
end;
36
48
 
37
49
{$ifdef wince}
41
53
Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
42
54
begin
43
55
  softfloat_exception_flags:=0;
 
56
end;
 
57
 
 
58
{$define FPC_SYSTEM_HAS_SYSINITFPU}
 
59
Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
 
60
begin
44
61
  softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
45
62
  { Enable FPU exceptions, but disable INEXACT, UNDERFLOW, DENORMAL }
46
63
  { FPU precision 64 bit, rounding to nearest, affine infinity }
57
74
function get_frame:pointer;assembler;nostackframe;{$ifdef SYSTEMINLINE}inline;{$endif}
58
75
asm
59
76
  mov    r0,r11
60
 
end ['R0'];
 
77
end;
61
78
{$ENDIF not INTERNAL_BACKTRACE}
62
79
 
63
80
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
67
84
  beq .Lg_a_null
68
85
  ldr r0,[r0,#-4]
69
86
.Lg_a_null:
70
 
end ['R0'];
 
87
end;
71
88
 
72
89
 
73
90
{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
77
94
  beq .Lgnf_null
78
95
  ldr r0,[r0,#-12]
79
96
.Lgnf_null:
80
 
end ['R0'];
 
97
end;
81
98
 
82
99
 
83
100
{$define FPC_SYSTEM_HAS_SPTR}
84
101
Function Sptr : pointer;assembler;{$ifdef SYSTEMINLINE}inline;{$endif}
85
102
asm
86
103
  mov    r0,sp
87
 
end ['R0'];
88
 
 
89
 
 
 
104
end;
 
105
 
 
106
 
 
107
{$ifndef FPC_SYSTEM_HAS_FILLCHAR}
90
108
{$define FPC_SYSTEM_HAS_FILLCHAR}
91
109
Procedure FillChar(var x;count:longint;value:byte);assembler;nostackframe;
92
110
asm
136
154
        strb r2,[r3],#1
137
155
        mov pc,lr
138
156
end;
139
 
 
 
157
{$endif FPC_SYSTEM_HAS_FILLCHAR}
140
158
 
141
159
{$ifndef FPC_SYSTEM_HAS_MOVE}
142
160
{$define FPC_SYSTEM_HAS_MOVE}
143
 
{$define FPC_SYSTEM_FPC_MOVE}
144
161
procedure Move_pld(const source;var dest;count:longint);assembler;nostackframe;
145
162
asm
146
163
  pld [r0]
290
307
 
291
308
{$endif FPC_SYSTEM_HAS_MOVE}
292
309
 
 
310
{****************************************************************************
 
311
                                 String
 
312
****************************************************************************}
 
313
 
 
314
{$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
 
315
{$define FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
 
316
 
 
317
{$ifndef FPC_STRTOSHORTSTRINGPROC}
 
318
function fpc_shortstr_to_shortstr(len:longint;const sstr:shortstring):shortstring;assembler;nostackframe;[public,alias: 'FPC_SHORTSTR_TO_SHORTSTR'];compilerproc;
 
319
{$else}
 
320
procedure fpc_shortstr_to_shortstr(out res:shortstring;const sstr:shortstring);assembler;nostackframe;[public,alias: 'FPC_SHORTSTR_TO_SHORTSTR'];compilerproc;
 
321
{$endif}
 
322
{r0: __RESULT
 
323
 r1: len
 
324
 r2: sstr}
 
325
 
 
326
asm
 
327
    ldrb r12,[r2],#1
 
328
    cmp  r12,r1
 
329
    movgt r12,r1
 
330
    strb r12,[r0],#1
 
331
    cmp  r12,#6 (* 6 seems to be the break even point. *)
 
332
    blt  .LStartTailCopy
 
333
    (* Align destination on 32bits. This is the only place where unrolling
 
334
       really seems to help, since in the common case, sstr is aligned on
 
335
       32 bits, therefore in the common case we need to copy 3 bytes to
 
336
       align, i.e. in the case of a loop, you wouldn't branch out early.*)
 
337
    rsb  r3,r0,#0
 
338
    ands  r3,r3,#3
 
339
    sub  r12,r12,r3
 
340
    ldrneb r1,[r2],#1
 
341
    strneb r1,[r0],#1
 
342
    subnes  r3,r3,#1
 
343
    ldrneb r1,[r2],#1
 
344
    strneb r1,[r0],#1
 
345
    subnes  r3,r3,#1
 
346
    ldrneb r1,[r2],#1
 
347
    strneb r1,[r0],#1
 
348
    subnes  r3,r3,#1
 
349
.LDoneAlign:
 
350
    (* Destination should be aligned now, but source might not be aligned,
 
351
       if this is the case, do a byte-per-byte copy. *)
 
352
    tst r2,#3
 
353
    bne .LStartTailCopy
 
354
    (* Start the main copy, 32 bit at a time. *)
 
355
    movs r3,r12,lsr #2
 
356
    and r12,r12,#3
 
357
    beq  .LStartTailCopy
 
358
.LNext4bytes:
 
359
    (* Unrolling this loop would save a little bit of time for long strings
 
360
       (>20 chars), but alas, it hurts for short strings and they are the
 
361
       common case.*)
 
362
    ldrne r1,[r2],#4
 
363
    strne r1,[r0],#4
 
364
    subnes  r3,r3,#1
 
365
    bne .LNext4bytes
 
366
.LStartTailCopy:
 
367
    (* Do remaining bytes. *)
 
368
    cmp r12,#0
 
369
    beq .LDoneTail
 
370
.LNextChar3:
 
371
    ldrb r1,[r2],#1
 
372
    strb r1,[r0],#1
 
373
    subs  r12,r12,#1
 
374
    bne .LNextChar3
 
375
.LDoneTail:
 
376
end;
 
377
 
 
378
procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer);assembler;nostackframe;[public,alias:'FPC_SHORTSTR_ASSIGN'];compilerproc;
 
379
 
 
380
{r0: len
 
381
 r1: sstr
 
382
 r2: dstr}
 
383
 
 
384
asm
 
385
    ldrb r12,[r1],#1
 
386
    cmp  r12,r0
 
387
    movgt r12,r0
 
388
    strb r12,[r2],#1
 
389
    cmp  r12,#6 (* 6 seems to be the break even point. *)
 
390
    blt  .LStartTailCopy
 
391
    (* Align destination on 32bits. This is the only place where unrolling
 
392
       really seems to help, since in the common case, sstr is aligned on
 
393
       32 bits, therefore in the common case we need to copy 3 bytes to
 
394
       align, i.e. in the case of a loop, you wouldn't branch out early.*)
 
395
    rsb  r3,r2,#0
 
396
    ands  r3,r3,#3
 
397
    sub  r12,r12,r3
 
398
    ldrneb r0,[r1],#1
 
399
    strneb r0,[r2],#1
 
400
    subnes  r3,r3,#1
 
401
    ldrneb r0,[r1],#1
 
402
    strneb r0,[r2],#1
 
403
    subnes  r3,r3,#1
 
404
    ldrneb r0,[r1],#1
 
405
    strneb r0,[r2],#1
 
406
    subnes  r3,r3,#1
 
407
.LDoneAlign:
 
408
    (* Destination should be aligned now, but source might not be aligned,
 
409
       if this is the case, do a byte-per-byte copy. *)
 
410
    tst r1,#3
 
411
    bne .LStartTailCopy
 
412
    (* Start the main copy, 32 bit at a time. *)
 
413
    movs r3,r12,lsr #2
 
414
    and r12,r12,#3
 
415
    beq  .LStartTailCopy
 
416
.LNext4bytes:
 
417
    (* Unrolling this loop would save a little bit of time for long strings
 
418
       (>20 chars), but alas, it hurts for short strings and they are the
 
419
       common case.*)
 
420
    ldrne r0,[r1],#4
 
421
    strne r0,[r2],#4
 
422
    subnes  r3,r3,#1
 
423
    bne .LNext4bytes
 
424
.LStartTailCopy:
 
425
    (* Do remaining bytes. *)
 
426
    cmp r12,#0
 
427
    beq .LDoneTail
 
428
.LNextChar3:
 
429
    ldrb r0,[r1],#1
 
430
    strb r0,[r2],#1
 
431
    subs  r12,r12,#1
 
432
    bne .LNextChar3
 
433
.LDoneTail:
 
434
end;
 
435
{$endif FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
 
436
 
 
437
{$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
 
438
{$define FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
 
439
function fpc_Pchar_length(p:Pchar):longint;assembler;nostackframe;[public,alias:'FPC_PCHAR_LENGTH'];compilerproc;
 
440
 
 
441
asm
 
442
    mov r1,r0
 
443
.Lnextchar:
 
444
    (*Are we aligned?*)
 
445
    tst r1,#3
 
446
    bne .Ltest_unaligned    (*No, do byte per byte.*)
 
447
    ldr r3,.L01010101
 
448
.Ltest_aligned:
 
449
    (*Aligned, load 4 bytes at a time.*)
 
450
    ldr r12,[r1],#4
 
451
    (*Check wether r12 contains a 0 byte.*)
 
452
    sub r2,r12,r3
 
453
    mvn r12,r12
 
454
    and r2,r2,r12
 
455
    ands r2,r2,r3,lsl #7    (*r3 lsl 7 = $80808080*)
 
456
    beq .Ltest_aligned      (*No 0 byte, repeat.*)
 
457
    sub r1,r1,#4
 
458
.Ltest_unaligned:
 
459
    ldrb r12,[r1],#1
 
460
    cmp r12,#1              (*r12<1 same as r12=0, but result in carry flag*)
 
461
    bcs .Lnextchar
 
462
    (*Dirty trick: we need to subtract 1 extra because we have counted the
 
463
      terminating 0, due to the known carry flag sbc can do this.*)
 
464
    sbc r0,r1,r0
 
465
    mov pc,lr
 
466
.L01010101:
 
467
    .long 0x01010101
 
468
end;
 
469
{$endif}
 
470
 
 
471
 
293
472
var
294
473
  fpc_system_lock: longint; export name 'fpc_system_lock';
295
474
 
406
585
 
407
586
procedure fpc_cpucodeinit;
408
587
begin
 
588
{$ifdef FPC_SYSTEM_FPC_MOVE}
409
589
  cpu_has_edsp:=true;
410
590
  in_edsp_test:=true;
411
591
  asm
412
 
    pld [r0]
 
592
    bic r0,sp,#7
 
593
    ldrd r0,[r0]
413
594
  end;
414
595
  in_edsp_test:=false;
415
 
{$ifdef FPC_SYSTEM_FPC_MOVE}
416
596
  if cpu_has_edsp then
417
597
    moveproc:=@move_pld
418
598
  else
419
599
    moveproc:=@move_blended;
420
600
{$endif FPC_SYSTEM_FPC_MOVE}
421
601
end;
 
602
 
 
603
{include hand-optimized assembler division code}
 
604
{$i divide.inc}
 
605