diff options
author | sergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-09-15 19:41:34 +0000 |
---|---|---|
committer | sergei <sergei@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-09-15 19:41:34 +0000 |
commit | 7c89e0ca2272f6e9724e994d17a0752fffec0251 (patch) | |
tree | 9b892808f3afdf8f174ad64dd58fd7f6a0c768fb /rtl/mips | |
parent | 3a71ec0858e29d3229ab4e1427601192f33fc17c (diff) | |
download | fpc-7c89e0ca2272f6e9724e994d17a0752fffec0251.tar.gz |
+ MIPS: Assembler implementation of FillChar
* Removed commented out assembler implementations of Inclocked(longint) and Declocked(longint) and replaced them with calls to InterlockedIncrement/Decrement, so they actually do the locking.
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@28672 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'rtl/mips')
-rw-r--r-- | rtl/mips/mips.inc | 183 |
1 files changed, 64 insertions, 119 deletions
diff --git a/rtl/mips/mips.inc b/rtl/mips/mips.inc index 0ff662aca6..e215f6b63a 100644 --- a/rtl/mips/mips.inc +++ b/rtl/mips/mips.inc @@ -204,6 +204,63 @@ function Sptr:Pointer;assembler;nostackframe; move $2,$sp end; +{$ifndef FPC_SYSTEM_HAS_FILLCHAR} +{$define FPC_SYSTEM_HAS_FILLCHAR} +procedure FillChar(var x;count:SizeInt;value:byte);assembler;nostackframe; +// x=$a0, count=$a1, value=$a2 +// $t0 and $t1 used as temps + asm + // correctness of this routine depends on instructions in delay slots!! + slti $t1, $a1, 8 + bne $t1, $0, .Lless8 + andi $a2, 0xff + + beq $a2, $0, .L1 // if value is zero, expansion can be skipped + sll $t1, $a2, 8 + or $a2, $t1 + sll $t1, $a2, 16 + or $a2, $t1 +.L1: + subu $t1, $0, $a0 // negate + andi $t1, 3 // misalignment 0..3 + beq $t1, $0, .L2 + subu $a1, $t1 // decrease count (if branching, this is no-op because $t1=0) +{$ifdef ENDIAN_BIG} + swl $a2, 0($a0) +{$else ENDIAN_BIG} + swr $a2, 0($a0) +{$endif ENDIAN_BIG} + addu $a0, $t1 // add misalignment to address, making it dword-aligned +.L2: + andi $t1, $a1, 7 // $t1=count mod 8 + beq $t1, $a1, .L3 // (count and 7)=count => (count and (not 7))=0 + subu $t0, $a1, $t1 // $t0=count div 8 + addu $t0, $a0 // $t0=last loop address + move $a1, $t1 +.Lloop8: // do 2 dwords per iteration + addiu $a0, 8 + sw $a2, -8($a0) + bne $a0, $t0, .Lloop8 + sw $a2, -4($a0) +.L3: + andi $t1, $a1, 4 // handle a single dword separately + beq $t1, $0, .Lless8 + subu $a1, $t1 + sw $a2, 0($a0) + addiu $a0, 4 + +.Lless8: + ble $a1, $0, .Lexit + addu $t0, $a1, $a0 +.L4: + addiu $a0, 1 + bne $a0, $t0, .L4 + sb $a2, -1($a0) +.Lexit: + end; +{$endif FPC_SYSTEM_HAS_FILLCHAR} + + {$ifdef USE_MIPS_STK2_ASM} {$ifndef FPC_SYSTEM_HAS_MOVE} (* Disabled for now @@ -411,132 +468,20 @@ procedure Move(const source;var dest;count:longint);[public, alias: 'FPC_MOVE']; end; *) {$endif FPC_SYSTEM_HAS_MOVE} -{**************************************************************************** - Integer math -****************************************************************************} - -var - fpc_system_lock : longint; export name 'fpc_system_lock'; - +{$endif def USE_MIPS_STK2_ASM} {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT} -function declocked(var l : longint) : boolean;assembler;nostackframe; -{ input: address of l in $4 } -{ output: boolean indicating whether l is zero after decrementing } -asm - sw $4,0($23) - sw $5,-4($23) - sw $6,-8($23) - sw $7,-12($23) - sw $8,-16($23) - sw $9,-20($23) - sw $10,-24($23) - sw $11,-28($23) - sw $12,-32($23) - sw $13,-36($23) - sw $14,-40($23) - addiu $23,$23,-44 - - - -.Ldeclocked1: - lui $5,%hi(fpc_system_lock) - addiu $5,$5,%lo(fpc_system_lock) - ll $6,0($5) - ori $7,$6,1 - beq $7,$6,.Ldeclocked1 - nop - sc $7,0($5) - - beq $7,$0,.Ldeclocked1 - nop - - lw $5,0($4) - addiu $5,$5,-1 - sw $5,0($4) - seq $2,$5,$0 - - - { unlock } - lui $5,%hi(fpc_system_lock) - addiu $5,$5,%lo(fpc_system_lock) - sw $0,0($5) - - addiu $23,$23,44 - lw $4,0($23) - lw $5,-4($23) - lw $6,-8($23) - lw $7,-12($23) - lw $8,-16($23) - lw $9,-20($23) - lw $10,-24($23) - lw $11,-28($23) - lw $12,-32($23) - lw $13,-36($23) - lw $14,-40($23) +function declocked(var l: longint) : boolean; inline; +begin + Result:=InterLockedDecrement(l) = 0; end; {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT} -procedure inclocked(var l : longint);assembler;nostackframe; -asm - { usually, we shouldn't lock here so saving the stack frame for these extra intructions is - worse the effort, especially while waiting :) - } - - { unlock } - - sw $4,0($23) - sw $5,-4($23) - sw $6,-8($23) - sw $7,-12($23) - sw $8,-16($23) - sw $9,-20($23) - sw $10,-24($23) - sw $11,-28($23) - sw $12,-32($23) - sw $13,-36($23) - sw $14,-40($23) - addiu $23,$23,-44 - - -.Ldeclocked1: - lui $5,%hi(fpc_system_lock) - addiu $5,$5,%lo(fpc_system_lock) - ll $6,0($5) - ori $7,$6,1 - beq $7,$6,.Ldeclocked1 - nop - sc $7,0($5) - - beq $7,$0,.Ldeclocked1 - nop - - lw $5,0($4) - addiu $5,$5,1 - sw $5,0($4) - - - { unlock } - lui $5,%hi(fpc_system_lock) - addiu $5,$5,%lo(fpc_system_lock) - sw $0,0($5) - - addiu $23,$23,44 - lw $4,0($23) - lw $5,-4($23) - lw $6,-8($23) - lw $7,-12($23) - lw $8,-16($23) - lw $9,-20($23) - lw $10,-24($23) - lw $11,-28($23) - lw $12,-32($23) - lw $13,-36($23) - lw $14,-40($23) - +procedure inclocked(var l: longint); inline; +begin + InterLockedIncrement(l); end; -{$endif def USE_MIPS_STK2_ASM} function InterLockedDecrement (var Target: longint) : longint; assembler; nostackframe; asm |