Selaa lähdekoodia

+ implementation for FPC_SET_SET_RANGE
* changed some routines so they never read data from after the actual
set (could cause sigsegv's if the set is at the end of the heap)

Jonas Maebe 25 vuotta sitten
vanhempi
commit
c9edb8c6e5
1 muutettua tiedostoa jossa 75 lisäystä ja 60 poistoa
  1. 75 60
      rtl/powerpc/set.inc

+ 75 - 60
rtl/powerpc/set.inc

@@ -123,45 +123,55 @@ end ['R3','R4'];
 
 procedure do_set_range(p : pointer;l,h : byte);assembler;[public,alias:'FPC_SET_SET_RANGE'];
 {
-  bad implementation, but it's very seldom used
-
   on entry: p in r3, l in r4, h in r5
 }
 var
   saveR6, saveR7, saveR8: longint;
 asm
-       cmplw    cr0,r4,r5
-       bg       cr0,.LSET_RANGE_EXIT
-       stw      r6,saveR6
-       stw      r7,saveR7
-       stw      r8,saveR8
-       
-       
-       
-       lwz      r7,(r3)
-       
-       
-
-        pushl   %eax
-        movl    p,%edi
-        xorl    %eax,%eax
-        xorl    %ecx,%ecx
-        movb    h,%al
-        movb    l,%cl
-.LSET_SET_RANGE_LOOP:
-        cmpl    %ecx,%eax
-        jl      .LSET_SET_RANGE_EXIT
-        movl    %eax,%ebx
-        movl    %eax,%edx
-        andl    $0xf8,%ebx
-        andl    $7,%edx
-        shrl    $3,%ebx
-        btsl    %edx,(%edi,%ebx)
-        dec     %eax
-        jmp     .LSET_SET_RANGE_LOOP
-.LSET_SET_RANGE_EXIT:
-        popl %eax
-end ['R4'];
+  cmplw  cr0,r4,r5
+  bg     cr0,.LSET_RANGE_EXIT
+  stw    r6,saveR6
+  stw    r7,saveR7
+  stw    r8,saveR8
+  rlwinm r6,r4,32-3,0,31-2    // divide by 8 to get starting and ending byte-
+  rlwinm r7,r5,32-3,0,31-2    // address and clear two lowest bits to get
+                              // start/end longint address * 4
+  sub.   r7,r6,r7             // are bit lo and hi in the same longint?
+  rlwinm r5,r5,0,31-4,31      // hi := hi mod 32 (= "hi and 31", but the andi
+                              // instr. only exists in flags modifying form)
+  eqv    r8,r8,r8             // r8 = $0x0ffffffff = bitmask to be inserted
+  subfic r5,r5,32             // hi := 32 - (hi mod 32) = shift count for later
+  srw    r8,r8,r4             // shift bitmask to clear bits below lo
+                              // note: shift right = opposite little endian!!
+  lwzu   r4,r3,r6             // go to starting pos in set and load value
+                              // (lo is not necessary anymore)
+  beq    .Lset_range_hi       // if bit lo and hi in same longint, keep
+                              // current mask and adjust for hi bit
+  subic. r7,r7,4              // bit hi in next longint?
+  or     r4,r4,r8             // merge and
+  stw    r4,(r3)              // store current mask
+  eqv    r8,r8,r8             // new mask
+  lwzu   r4,4(r3)             // load next longint of set
+  beq    .Lset_range_hi       // bit hi in this longint -> go to adjust for hi
+.Lset_range_loop:
+  subic. r7,r7,4
+  stwu   r8,4(r3)             // fill longints in between with full mask
+  bne    .Lset_range_loop
+  lwzu    r4,4(r3)            // load next value from set
+.Lset_range_hi:               // in all cases, r3 here contains the address of
+                              // the longint which contains the hi bit and r9
+                              // contains this longint
+  slw    r7,r8,r5             // r7 := bitmask shl (32 - (hi mod 32)) =
+                              // bitmask with bits higher than hi cleared
+  and    r8,r7,r8             // combine lo and hi bitmasks for this longint
+  or     r4,r4,r8             // and combine with existing set
+  stw    r4,(r3)              // store to set
+.Lset_range_done:
+  lwz    r6,saver6
+  lwz    r7,saver7
+  lwz    r8,saver8
+.Lset_range_exit:
+end ['R3','R4','R5'];
 
 
 procedure do_in_byte(p : pointer;b : byte);assembler;[public,alias:'FPC_SET_IN_BYTE'];
@@ -206,14 +216,14 @@ asm
        subi     r5,r5,4
        li       r6,8
        stw      r8,saveR8
-       lwz      r7,(r3)
-       lwz      r8,(r4)
+       subi     r3,4
+       subi     r4,4
    .LMADDSETS1:
-      subi.     r6,r6,1
-      or        r7,r7,r8
+      subic.    r6,r6,1
+      lwzu      r7,4(r3)
       lwzu      r8,4(r4)
+      or        r7,r7,r8
       stwu      r7,4(r5)
-      lwzu      r7,4(r3)
       bne       cr0,.LMADDSETS1
       lwz       r6,saveR6
       lwz       r7,saveR7
@@ -235,14 +245,14 @@ asm
        subi     r5,r5,4
        li       r6,8
        stw      r8,saveR8
-       lwz      r7,(r3)
-       lwz      r8,(r4)
+       subi     r3,4
+       subi     r4,4
    .LMADDSETS1:
-       subi.    r6,r6,1
-       and      r7,r7,r8
+       subic.   r6,r6,1
+       lwzu     r7,4(r3)
        lwzu     r8,4(r4)
+       and      r7,r7,r8
        stwu     r7,4(r5)
-       lwzu     r7,4(r3)
        bne      cr0,.LMADDSETS1
        lwz      r6,saveR6
        lwz      r7,saveR7
@@ -264,14 +274,14 @@ asm
        subi     r5,r5,4
        li       r6,8
        stw      r8,saveR8
-       lwz      r7,(r3)
-       lwz      r8,(r4)
+       subi     r3,4
+       subi     r4,4
    .LMSUBSETS1:
        subi.    r6,r6,1
-       andc     r8,r8,r7
+       lwzu     r8,4(r4)
        lwzu     r7,4(r3)
+       andc     r8,r8,r7
        stwu     r8,4(r5)
-       lwzu     r8,4(r4)
        bne      cr0,.LMSUBSETS1
        lwz      r6,saveR6
        lwz      r7,saveR7
@@ -293,14 +303,14 @@ asm
        subi     r5,r5,4
        li       r6,8
        stw      r8,saveR8
-       lwz      r7,(r3)
-       lwz      r8,(r4)
+       subi     r3,4
+       subi     r4,4
    .LMSYMDIFSETS1:
        subi.    r6,r6,1
-       xor      r7,r7,r8
+       lwzu     r7,4(r3)
        lwzu     r8,4(r4)
+       xor      r7,r7,r8
        stwu     r7,4(r5)
-       lwzu     r7,4(r3)
        bne      cr0,.LMSYMDIFSETS1
        lwz      r6,saveR6
        lwz      r7,saveR7
@@ -323,12 +333,12 @@ asm
        li       r6,8
        stw      r7,saveR7
        mtctr    r6
-       lwz      r6,(r3)
-       lwz      r7,(r4)
+       subi     r3,4
+       subi     r4,4
     .LMCOMPSETS1:
-       cmplw    cr0,r6,r7
        lwzu     r6,4(r3)
        lwzu     r7,4(r4)
+       cmplw    cr0,r6,r7
        bdnzeq   cr0,.LMCOMPSETS1
        mtctr    r5
        lwz      r5,saveR5
@@ -351,12 +361,12 @@ asm
        li       r6,8
        stw      r7,saveR7
        mtctr    r6
-       lwz      r6,(r3)
-       lwz      r7,(r4)
+       subi     r3,4
+       subi     r4,4
     .LMCOMPSETS1:
-       andc.    r7,r6,r7
-       lwzu     r6,4(r3)
        lwzu     r7,4(r4)
+       lwzu     r6,4(r3)
+       andc.    r7,r6,r7
        bdnzeq   cr0,.LMCOMPSETS1
        mtctr    r5
        lwz      r5,saveR5
@@ -530,7 +540,12 @@ end;
 
 {
   $Log$
-  Revision 1.2  2000-07-13 11:33:56  michael
+  Revision 1.3  2000-09-22 10:03:18  jonas
+    + implementation for FPC_SET_SET_RANGE
+    * changed some routines so they never read data from after the actual
+      set (could cause sigsegv's if the set is at the end of the heap)
+
+  Revision 1.2  2000/07/13 11:33:56  michael
   + removed logs
  
 }