summaryrefslogtreecommitdiff
path: root/rtl/powerpc
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2007-05-19 17:15:15 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2007-05-19 17:15:15 +0000
commite59661ad922265f08814f2e195d1cd852b4ad752 (patch)
tree88027d8f1f9693d64d283a3bc4640407ff1891f0 /rtl/powerpc
parent9ac38fb027825418603ebf4b20b928855f41fd7b (diff)
downloadfpc-e59661ad922265f08814f2e195d1cd852b4ad752.tar.gz
* new internal set format for big endian systems. Advantages:
* varsets ({$packset x}) are now supported on big endian targets * gdb now displays sets properly on big endian systems * cleanup of generic set code (in, include/exclude, helpers), all based on "bitpacked array[] of 0..1" now * there are no helpers available yet to convert sets from the old to the new format, because the set format will change again slightly in the near future (so that e.g. a set of 24..31 will be stored in 1 byte), and creating two classes of set conversion helpers would confuse things (i.e., it's not recommended to use trunk currently for programs which load sets stored to disk by big endian programs compiled by previous FPC versions) * cross-endian compiling has been tested and still works, but one case is not supported: compiling a compiler for a different endianess using a starting compiler from before the current revision (so first cycle natively, and then use the newly created compiler to create a cross-compiler) git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@7395 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'rtl/powerpc')
-rw-r--r--rtl/powerpc/set.inc227
1 files changed, 37 insertions, 190 deletions
diff --git a/rtl/powerpc/set.inc b/rtl/powerpc/set.inc
index 4fe6e5247c..d39e72dbb1 100644
--- a/rtl/powerpc/set.inc
+++ b/rtl/powerpc/set.inc
@@ -53,6 +53,7 @@ asm
stw r0,24(r3)
stw r0,28(r3)
+{$ifndef FPC_NEW_BIGENDIAN_SETS}
// r0 := 1 shl r4[27-31] -> bit index in dword (rotate instructions
// with count in register only consider lower 5 bits of this register)
li r0,1
@@ -62,9 +63,17 @@ asm
// (((b div 8) div 4)*4= (b div 8) and not(3))
// r5 := (r4 rotl(32-3)) and (0x01ffffff8)
rlwinm r4,r4,31-3+1,3,31-2
-
// store the result
stwx r0,r3,r4
+{$else}
+ { must be done byte- instead of dword-based }
+ rlwinm r5,r4,0,31-3+1,31
+ li r0,0x80
+ srw r0,r0,r5
+ srwi r4,r4,3
+ // store the result
+ stbx r0,r3,r4
+{$endif}
end;
@@ -86,6 +95,7 @@ asm
stfd f2,16(r3)
stfd f3,24(r3)
+{$ifndef FPC_NEW_BIGENDIAN_SETS}
// get the index of the correct *dword* in the set
// r0 := (r5 rotl(32-3)) and (0x0fffffff8)
rlwinm r0,r5,31-3+1,3,31-2
@@ -99,6 +109,17 @@ asm
or r5,r4,r5
// store result
stw r5,0(r3)
+{$else}
+ { must be done byte- instead of dword-based }
+ srwi r6,r5,3
+ lbzx r7,r6,r3
+ rlwinm r5,r5,0,31-3+1,31
+ li r0,0x80
+ srw r0,r0,r5
+ or r7,r7,r0
+ // store the result
+ stbx r7,r6,r3
+{$endif}
end;
@@ -120,6 +141,7 @@ asm
stfd f1,8(r3)
stfd f2,16(r3)
stfd f3,24(r3)
+{$ifndef FPC_NEW_BIGENDIAN_SETS}
// get the index of the correct *dword* in the set
// r0 := (r4 rotl(32-3)) and (0x0fffffff8)
rlwinm r0,r5,31-3+1,3,31-2
@@ -132,9 +154,22 @@ asm
andc r5,r4,r5
// store result
stw r4,0(r3)
+{$else}
+ { must be done byte- instead of dword-based }
+ srwi r6,r5,3
+ lbzx r7,r6,r3
+ rlwinm r5,r5,0,31-3+1,31
+ li r0,0x80
+ srw r0,r0,r5
+ andc r7,r7,r0
+ // store the result
+ stbx r7,r6,r3
+{$endif}
end;
+{$ifndef FPC_NEW_BIGENDIAN_SETS}
+
{$define FPC_SYSTEM_HAS_FPC_SET_SET_RANGE}
function fpc_set_set_range(const orgset: fpc_normal_set; l,h : byte): fpc_normal_set;assembler; compilerproc;
{
@@ -196,29 +231,7 @@ asm
stw r5,0(r3) // store to set
.Lset_range_exit:
end;
-
-
-{$define FPC_SYSTEM_HAS_FPC_SET_IN_BYTE}
-function fpc_set_in_byte(const p: fpc_normal_set; b : byte): boolean;compilerproc;assembler;[public,alias:'FPC_SET_IN_BYTE'];
-{
- tests if the element b is in the set p, the **zero** flag is cleared if it's present
-
- on entry: p in r3, b in r4
-}
-asm
- // get the index of the correct *dword* in the set
- // r0 := (r4 rotl(32-3)) and (0x0fffffff8)
- rlwinm r0,r4,31-3+1,3,31-2
-
- // load dword in which the bit has to be tested
- lwzx r3,r3,r0
-
- // r4 := 32 - r4 (no problem if r4 > 32, the rlwnm next does a mod 32)
- subfic r4,r4,32
- // r3 := (r3 shr (r4 mod 32)) and 1
- rlwnm r3,r3,r4,31,31
-end;
-
+{$endif}
{$define FPC_SYSTEM_HAS_FPC_SET_ADD_SETS}
@@ -354,169 +367,3 @@ asm
cntlzw r3,r0
srwi. r3,r3,5
end;
-
-
-
-{$ifdef LARGESETS}
-
-procedure do_set(p : pointer;b : word);assembler;[public,alias:'FPC_SET_SET_WORD'];
-{
- sets the element b in set p works for sets larger than 256 elements
- not yet use by the compiler so
-}
-asm
- pushl %eax
- movl p,%edi
- movw b,%ax
- andl $0xfff8,%eax
- shrl $3,%eax
- addl %eax,%edi
- movb 12(%ebp),%al
- andl $7,%eax
- btsl %eax,(%edi)
- popl %eax
-end;
-
-
-procedure do_in(p : pointer;b : word);assembler;[public,alias:'FPC_SET_IN_WORD'];
-{
- tests if the element b is in the set p the carryflag is set if it present
- works for sets larger than 256 elements
-}
-asm
- pushl %eax
- movl p,%edi
- movw b,%ax
- andl $0xfff8,%eax
- shrl $3,%eax
- addl %eax,%edi
- movb 12(%ebp),%al
- andl $7,%eax
- btl %eax,(%edi)
- popl %eax
-end;
-
-
-procedure add_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_ADD_SETS_SIZE'];
-{
- adds set1 and set2 into set dest size is the number of bytes in the set
-}
-asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl size,%ecx
- .LMADDSETSIZES1:
- lodsl
- orl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMADDSETSIZES1
-end;
-
-
-procedure mul_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_MUL_SETS_SIZE'];
-{
- multiplies (i.E. takes common elements of) set1 and set2 result put in
- dest size is the number of bytes in the set
-}
-asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl size,%ecx
- .LMMULSETSIZES1:
- lodsl
- andl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMMULSETSIZES1
-end;
-
-
-procedure sub_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_SUB_SETS_SIZE'];
-asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl size,%ecx
- .LMSUBSETSIZES1:
- lodsl
- movl (%ebx),%edx
- notl %edx
- andl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMSUBSETSIZES1
-end;
-
-
-procedure sym_sub_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_SYMDIF_SETS_SIZE'];
-{
- computes the symetric diff from set1 to set2 result in dest
-}
-asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl size,%ecx
- .LMSYMDIFSETSIZE1:
- lodsl
- movl (%ebx),%edx
- xorl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz LMSYMDIFSETSIZE1
-end;
-
-
-procedure comp_sets(set1,set2 : pointer;size : longint);assembler;[public,alias:'FPC_SET_COMP_SETS_SIZE'];
-asm
- movl set1,%esi
- movl set2,%edi
- movl size,%ecx
- LMCOMPSETSIZES1:
- lodsl
- movl (%edi),%edx
- cmpl %edx,%eax
- jne LMCOMPSETSIZEEND
- addl $4,%edi
- decl %ecx
- jnz LMCOMPSETSIZES1
- { we are here only if the two sets are equal
- we have zero flag set, and that what is expected }
- LMCOMPSETSIZEEND:
-end;
-
-{$IfNDef NoSetInclusion}
-procedure contains_sets(set1,set2 : pointer; size: longint);assembler;[public,alias:'FPC_SET_CONTAINS_SETS'];
-{
- on exit, zero flag is set if set1 <= set2 (set2 contains set1)
-}
-asm
- movl set1,%esi
- movl set2,%edi
- movl size,%ecx
- LMCONTAINSSETS2:
- movl (%esi),%eax
- movl (%edi),%edx
- andl %eax,%edx
- cmpl %edx,%eax {set1 and set2 = set1?}
- jne LMCONTAINSSETEND2
- addl $4,%esi
- addl $4,%edi
- decl %ecx
- jnz LMCONTAINSSETS2
- { we are here only if set2 contains set1
- we have zero flag set, and that what is expected }
- LMCONTAINSSETEND2:
-end;
-{$EndIf NoSetInclusion}
-
-
-{$endif LARGESET}
-