|
@@ -1,9 +1,8 @@
|
|
|
{
|
|
|
-
|
|
|
This file is part of the Free Pascal run time library.
|
|
|
Copyright (c) 2000-2001 by the Free Pascal development team.
|
|
|
|
|
|
- Portions Copyright (c) 2000 by Casey Duncan ([email protected])
|
|
|
+ Portions Copyright (c) 2000 by Casey Duncan ([email protected])
|
|
|
|
|
|
Processor dependent implementation for the system unit for
|
|
|
PowerPC64
|
|
@@ -22,16 +21,7 @@
|
|
|
PowerPC specific stuff
|
|
|
****************************************************************************}
|
|
|
|
|
|
-const
|
|
|
- ppc_fpu_overflow = (1 shl (32-3));
|
|
|
- ppc_fpu_underflow = (1 shl (32-4));
|
|
|
- ppc_fpu_divbyzero = (1 shl (32-5));
|
|
|
- ppc_fpu_inexact = (1 shl (32-6));
|
|
|
- ppc_fpu_invalid_snan = (1 shl (32-7));
|
|
|
-
|
|
|
-
|
|
|
-procedure fpc_enable_ppc_fpu_exceptions;
|
|
|
-assembler; nostackframe;
|
|
|
+procedure fpc_enable_ppc_fpu_exceptions; assembler; nostackframe;
|
|
|
asm
|
|
|
{ clear all "exception happened" flags we care about}
|
|
|
mtfsfi 0,0
|
|
@@ -42,7 +32,6 @@ asm
|
|
|
mtfsb0 21
|
|
|
mtfsb0 22
|
|
|
mtfsb0 23
|
|
|
-
|
|
|
{$endif fpc_mtfsb0_corrected}
|
|
|
|
|
|
{ enable invalid operations and division by zero exceptions. }
|
|
@@ -57,358 +46,6 @@ begin
|
|
|
fpc_enable_ppc_fpu_exceptions;
|
|
|
end;
|
|
|
|
|
|
-
|
|
|
-function fpc_get_ppc_fpscr: cardinal;
|
|
|
-assembler;
|
|
|
-var
|
|
|
- temp: record a,b:longint; end;
|
|
|
-asm
|
|
|
- mffs f0
|
|
|
- stfd f0,temp
|
|
|
- lwz r3,temp.b
|
|
|
- { clear all exception flags }
|
|
|
-{ TODO
|
|
|
- rlwinm r4,r3,0,16,31
|
|
|
- stw r4,temp.b
|
|
|
- lfd f0,temp
|
|
|
- mtfsf f0
|
|
|
-
}
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
-{ note: unused; to be moved into startup code }
|
|
|
-{ The following code is never called directly, it's a dummy which holds the
|
|
|
-entry points and code to the register save/load subroutines; it is part of the
|
|
|
-PPC ABI and used in procedure entry and exit methods.
|
|
|
-See the comments in the code for "calling conventions". Directly taken from
|
|
|
-the ABI specification. The labels right below are required to shut up the
|
|
|
-compiler. }
|
|
|
-
|
|
|
-label
|
|
|
- // _savegpr0_x
|
|
|
- _savegpr0_14, _savegpr0_15, _savegpr0_16, _savegpr0_17, _savegpr0_18, _savegpr0_19,
|
|
|
- _savegpr0_20, _savegpr0_21, _savegpr0_22, _savegpr0_23, _savegpr0_24, _savegpr0_25,
|
|
|
- _savegpr0_26, _savegpr0_27, _savegpr0_28, _savegpr0_29, _savegpr0_30, _savegpr0_31,
|
|
|
- // _restgpr0_x
|
|
|
- _restgpr0_14, _restgpr0_15, _restgpr0_16, _restgpr0_17, _restgpr0_18, _restgpr0_19,
|
|
|
- _restgpr0_20, _restgpr0_21, _restgpr0_22, _restgpr0_23, _restgpr0_24, _restgpr0_25,
|
|
|
- _restgpr0_26, _restgpr0_27, _restgpr0_28, _restgpr0_29, _restgpr0_30, _restgpr0_31,
|
|
|
- // _savegpr1_x
|
|
|
- _savegpr1_14, _savegpr1_15, _savegpr1_16, _savegpr1_17, _savegpr1_18, _savegpr1_19,
|
|
|
- _savegpr1_20, _savegpr1_21, _savegpr1_22, _savegpr1_23, _savegpr1_24, _savegpr1_25,
|
|
|
- _savegpr1_26, _savegpr1_27, _savegpr1_28, _savegpr1_29, _savegpr1_30, _savegpr1_31,
|
|
|
- // _restgpr1_x
|
|
|
- _restgpr1_14, _restgpr1_15, _restgpr1_16, _restgpr1_17, _restgpr1_18, _restgpr1_19,
|
|
|
- _restgpr1_20, _restgpr1_21, _restgpr1_22, _restgpr1_23, _restgpr1_24, _restgpr1_25,
|
|
|
- _restgpr1_26, _restgpr1_27, _restgpr1_28, _restgpr1_29, _restgpr1_30, _restgpr1_31,
|
|
|
- // _savefpr_x
|
|
|
- _savefpr_14, _savefpr_15, _savefpr_16, _savefpr_17, _savefpr_18, _savefpr_19,
|
|
|
- _savefpr_20, _savefpr_21, _savefpr_22, _savefpr_23, _savefpr_24, _savefpr_25,
|
|
|
- _savefpr_26, _savefpr_27, _savefpr_28, _savefpr_29, _savefpr_30, _savefpr_31,
|
|
|
- // _restfpr_x
|
|
|
- _restfpr_14, _restfpr_15, _restfpr_16, _restfpr_17, _restfpr_18, _restfpr_19,
|
|
|
- _restfpr_20, _restfpr_21, _restfpr_22, _restfpr_23, _restfpr_24, _restfpr_25,
|
|
|
- _restfpr_26, _restfpr_27, _restfpr_28, _restfpr_29, _restfpr_30, _restfpr_31,
|
|
|
- // _savevr_x
|
|
|
- _savevr_20, _savevr_21, _savevr_22, _savevr_23, _savevr_24, _savevr_25,
|
|
|
- _savevr_26, _savevr_27, _savevr_28, _savevr_29, _savevr_30, _savevr_31,
|
|
|
- // _restvr_x
|
|
|
- _restvr_20, _restvr_21, _restvr_22, _restvr_23, _restvr_24, _restvr_25,
|
|
|
- _restvr_26, _restvr_27, _restvr_28, _restvr_29, _restvr_30, _restvr_31;
|
|
|
-
|
|
|
-
|
|
|
-procedure __save_restore_services; assembler; nostackframe;
|
|
|
-assembler;
|
|
|
-asm
|
|
|
-// Each _savegpr0_N routine saves the general registers from rN to r31, inclusive.
|
|
|
-// Each routine also saves the LR. When the routine is called, r1 must point to
|
|
|
-// the start of the general register save area, and r0 must contain the
|
|
|
-// value of LR on function entry.
|
|
|
-.globl _savegpr0_14
|
|
|
-_savegpr0_14: std r14,-144(r1)
|
|
|
-.globl _savegpr0_15
|
|
|
-_savegpr0_15: std r15,-136(r1)
|
|
|
-.globl _savegpr0_16
|
|
|
-_savegpr0_16: std r16,-128(r1)
|
|
|
-.globl _savegpr0_17
|
|
|
-_savegpr0_17: std r17,-120(r1)
|
|
|
-.globl _savegpr0_18
|
|
|
-_savegpr0_18: std r18,-112(r1)
|
|
|
-.globl _savegpr0_19
|
|
|
-_savegpr0_19: std r19,-104(r1)
|
|
|
-.globl _savegpr0_20
|
|
|
-_savegpr0_20: std r20,-96(r1)
|
|
|
-.globl _savegpr0_21
|
|
|
-_savegpr0_21: std r21,-88(r1)
|
|
|
-.globl _savegpr0_22
|
|
|
-_savegpr0_22: std r22,-80(r1)
|
|
|
-.globl _savegpr0_23
|
|
|
-_savegpr0_23: std r23,-72(r1)
|
|
|
-.globl _savegpr0_24
|
|
|
-_savegpr0_24: std r24,-64(r1)
|
|
|
-.globl _savegpr0_25
|
|
|
-_savegpr0_25: std r25,-56(r1)
|
|
|
-.globl _savegpr0_26
|
|
|
-_savegpr0_26: std r26,-48(r1)
|
|
|
-.globl _savegpr0_27
|
|
|
-_savegpr0_27: std r27,-40(r1)
|
|
|
-.globl _savegpr0_28
|
|
|
-_savegpr0_28: std r28,-32(r1)
|
|
|
-.globl _savegpr0_29
|
|
|
-_savegpr0_29: std r29,-24(r1)
|
|
|
-.globl _savegpr0_30
|
|
|
-_savegpr0_30: std r30,-16(r1)
|
|
|
-.globl _savegpr0_31
|
|
|
-_savegpr0_31: std r31,-8(r1)
|
|
|
- std r0, 16(r1)
|
|
|
- blr
|
|
|
-// The _restgpr0_N routines restore the general registers from rN to r31, and then
|
|
|
-// return to the caller. When the routine is called, r1 must point to the start of
|
|
|
-// the general register save area.
|
|
|
-.globl _restgpr0_14
|
|
|
-_restgpr0_14: ld r14,-144(r1)
|
|
|
-.globl _restgpr0_15
|
|
|
-_restgpr0_15: ld r15,-136(r1)
|
|
|
-.globl _restgpr0_16
|
|
|
-_restgpr0_16: ld r16,-128(r1)
|
|
|
-.globl _restgpr0_17
|
|
|
-_restgpr0_17: ld r17,-120(r1)
|
|
|
-.globl _restgpr0_18
|
|
|
-_restgpr0_18: ld r18,-112(r1)
|
|
|
-.globl _restgpr0_19
|
|
|
-_restgpr0_19: ld r19,-104(r1)
|
|
|
-.globl _restgpr0_20
|
|
|
-_restgpr0_20: ld r20,-96(r1)
|
|
|
-.globl _restgpr0_21
|
|
|
-_restgpr0_21: ld r21,-88(r1)
|
|
|
-.globl _restgpr0_22
|
|
|
-_restgpr0_22: ld r22,-80(r1)
|
|
|
-.globl _restgpr0_23
|
|
|
-_restgpr0_23: ld r23,-72(r1)
|
|
|
-.globl _restgpr0_24
|
|
|
-_restgpr0_24: ld r24,-64(r1)
|
|
|
-.globl _restgpr0_25
|
|
|
-_restgpr0_25: ld r25,-56(r1)
|
|
|
-.globl _restgpr0_26
|
|
|
-_restgpr0_26: ld r26,-48(r1)
|
|
|
-.globl _restgpr0_27
|
|
|
-_restgpr0_27: ld r27,-40(r1)
|
|
|
-.globl _restgpr0_28
|
|
|
-_restgpr0_28: ld r28,-32(r1)
|
|
|
-.globl _restgpr0_29
|
|
|
-_restgpr0_29: ld r0, 16(r1)
|
|
|
- ld r29,-24(r1)
|
|
|
- mtlr r0
|
|
|
- ld r30,-16(r1)
|
|
|
- ld r31,-8(r1)
|
|
|
- blr
|
|
|
-.globl _restgpr0_30
|
|
|
-_restgpr0_30: ld r30,-16(r1)
|
|
|
-.globl _restgpr0_31
|
|
|
-_restgpr0_31: ld r0, 16(r1)
|
|
|
- ld r31,-8(r1)
|
|
|
- mtlr r0
|
|
|
- blr
|
|
|
-// Each _savegpr1_N routine saves the general registers from rN to r31,
|
|
|
-// inclusive. When the routine is called, r12
|
|
|
-// must point to the start of the general register save area.
|
|
|
-.globl _savegpr1_14
|
|
|
-_savegpr1_14: std r14,-144(r12)
|
|
|
-.globl _savegpr1_15
|
|
|
-_savegpr1_15: std r15,-136(r12)
|
|
|
-.globl _savegpr1_16
|
|
|
-_savegpr1_16: std r16,-128(r12)
|
|
|
-.globl _savegpr1_17
|
|
|
-_savegpr1_17: std r17,-120(r12)
|
|
|
-.globl _savegpr1_18
|
|
|
-_savegpr1_18: std r18,-112(r12)
|
|
|
-.globl _savegpr1_19
|
|
|
-_savegpr1_19: std r19,-104(r12)
|
|
|
-.globl _savegpr1_20
|
|
|
-_savegpr1_20: std r20,-96(r12)
|
|
|
-.globl _savegpr1_21
|
|
|
-_savegpr1_21: std r21,-88(r12)
|
|
|
-.globl _savegpr1_22
|
|
|
-_savegpr1_22: std r22,-80(r12)
|
|
|
-.globl _savegpr1_23
|
|
|
-_savegpr1_23: std r23,-72(r12)
|
|
|
-.globl _savegpr1_24
|
|
|
-_savegpr1_24: std r24,-64(r12)
|
|
|
-.globl _savegpr1_25
|
|
|
-_savegpr1_25: std r25,-56(r12)
|
|
|
-.globl _savegpr1_26
|
|
|
-_savegpr1_26: std r26,-48(r12)
|
|
|
-.globl _savegpr1_27
|
|
|
-_savegpr1_27: std r27,-40(r12)
|
|
|
-.globl _savegpr1_28
|
|
|
-_savegpr1_28: std r28,-32(r12)
|
|
|
-.globl _savegpr1_29
|
|
|
-_savegpr1_29: std r29,-24(r12)
|
|
|
-.globl _savegpr1_30
|
|
|
-_savegpr1_30: std r30,-16(r12)
|
|
|
-.globl _savegpr1_31
|
|
|
-_savegpr1_31: std r31,-8(r12)
|
|
|
- blr
|
|
|
-// The _restgpr1_N routines restore the general registers from rN to r31.
|
|
|
-// When the routine is called, r12 must point to the start of the general
|
|
|
-// register save area.
|
|
|
-.globl _restgpr1_14
|
|
|
-_restgpr1_14: ld r14,-144(r12)
|
|
|
-.globl _restgpr1_15
|
|
|
-_restgpr1_15: ld r15,-136(r12)
|
|
|
-.globl _restgpr1_16
|
|
|
-_restgpr1_16: ld r16,-128(r12)
|
|
|
-.globl _restgpr1_17
|
|
|
-_restgpr1_17: ld r17,-120(r12)
|
|
|
-.globl _restgpr1_18
|
|
|
-_restgpr1_18: ld r18,-112(r12)
|
|
|
-.globl _restgpr1_19
|
|
|
-_restgpr1_19: ld r19,-104(r12)
|
|
|
-.globl _restgpr1_20
|
|
|
-_restgpr1_20: ld r20,-96(r12)
|
|
|
-.globl _restgpr1_21
|
|
|
-_restgpr1_21: ld r21,-88(r12)
|
|
|
-.globl _restgpr1_22
|
|
|
-_restgpr1_22: ld r22,-80(r12)
|
|
|
-.globl _restgpr1_23
|
|
|
-_restgpr1_23: ld r23,-72(r12)
|
|
|
-.globl _restgpr1_24
|
|
|
-_restgpr1_24: ld r24,-64(r12)
|
|
|
-.globl _restgpr1_25
|
|
|
-_restgpr1_25: ld r25,-56(r12)
|
|
|
-.globl _restgpr1_26
|
|
|
-_restgpr1_26: ld r26,-48(r12)
|
|
|
-.globl _restgpr1_27
|
|
|
-_restgpr1_27: ld r27,-40(r12)
|
|
|
-.globl _restgpr1_28
|
|
|
-_restgpr1_28: ld r28,-32(r12)
|
|
|
-.globl _restgpr1_29
|
|
|
-_restgpr1_29: ld r29,-24(r12)
|
|
|
-.globl _restgpr1_30
|
|
|
-_restgpr1_30: ld r30,-16(r12)
|
|
|
-.globl _restgpr1_31
|
|
|
-_restgpr1_31: ld r31,-8(r12)
|
|
|
- blr
|
|
|
-
|
|
|
-// Each _savefpr_M routine saves the floating point registers from fM to f31,
|
|
|
-// inclusive. When the routine is called, r1 must point to the start of the
|
|
|
-// floating point register save area, and r0 must contain the value of LR on
|
|
|
-// function entry.
|
|
|
-_savefpr_14: stfd f14,-144(r1)
|
|
|
-_savefpr_15: stfd f15,-136(r1)
|
|
|
-_savefpr_16: stfd f16,-128(r1)
|
|
|
-_savefpr_17: stfd f17,-120(r1)
|
|
|
-_savefpr_18: stfd f18,-112(r1)
|
|
|
-_savefpr_19: stfd f19,-104(r1)
|
|
|
-_savefpr_20: stfd f20,-96(r1)
|
|
|
-_savefpr_21: stfd f21,-88(r1)
|
|
|
-_savefpr_22: stfd f22,-80(r1)
|
|
|
-_savefpr_23: stfd f23,-72(r1)
|
|
|
-_savefpr_24: stfd f24,-64(r1)
|
|
|
-_savefpr_25: stfd f25,-56(r1)
|
|
|
-_savefpr_26: stfd f26,-48(r1)
|
|
|
-_savefpr_27: stfd f27,-40(r1)
|
|
|
-_savefpr_28: stfd f28,-32(r1)
|
|
|
-_savefpr_29: stfd f29,-24(r1)
|
|
|
-_savefpr_30: stfd f30,-16(r1)
|
|
|
-_savefpr_31: stfd f31,-8(r1)
|
|
|
- std r0, 16(r1)
|
|
|
- blr
|
|
|
-// The _restfpr_M routines restore the floating point registers from fM to f31.
|
|
|
-// When the routine is called, r1 must point to the start of the floating point
|
|
|
-// register save area.
|
|
|
-_restfpr_14: lfd f14,-144(r1)
|
|
|
-_restfpr_15: lfd f15,-136(r1)
|
|
|
-_restfpr_16: lfd f16,-128(r1)
|
|
|
-_restfpr_17: lfd f17,-120(r1)
|
|
|
-_restfpr_18: lfd f18,-112(r1)
|
|
|
-_restfpr_19: lfd f19,-104(r1)
|
|
|
-_restfpr_20: lfd f20,-96(r1)
|
|
|
-_restfpr_21: lfd f21,-88(r1)
|
|
|
-_restfpr_22: lfd f22,-80(r1)
|
|
|
-_restfpr_23: lfd f23,-72(r1)
|
|
|
-_restfpr_24: lfd f24,-64(r1)
|
|
|
-_restfpr_25: lfd f25,-56(r1)
|
|
|
-_restfpr_26: lfd f26,-48(r1)
|
|
|
-_restfpr_27: lfd f27,-40(r1)
|
|
|
-_restfpr_28: lfd f28,-32(r1)
|
|
|
-_restfpr_29: lfd f29,-24(r1)
|
|
|
-_restfpr_29: ld r0, 16(r1)
|
|
|
- lfd f29,-24(r1)
|
|
|
- mtlr r0
|
|
|
- lfd f30,-16(r1)
|
|
|
- lfd f31,-8(r1)
|
|
|
- blr
|
|
|
-_restfpr_30: lfd f30,-16(r1)
|
|
|
-_restfpr_31: ld r0, 16(r1)
|
|
|
- lfd f31,-8(r1)
|
|
|
- mtlr r0
|
|
|
- blr
|
|
|
-// Each _savevr_M routine saves the vector registers from vM to v31, inclusive.
|
|
|
-// When the routine is called, r0 must point to the word just beyound the end
|
|
|
-// of the vector register save area. On return the value of r0 is unchanged
|
|
|
-// while r12 may be modified.
|
|
|
-(* commented out: GAS does not understand VMX opcodes?
|
|
|
-_savevr_20: addi r12,r0,-192
|
|
|
- stvx v20,r12,r0
|
|
|
-_savevr_21: addi r12,r0,-176
|
|
|
- stvx v21,r12,r0
|
|
|
-_savevr_22: addi r12,r0,-160
|
|
|
- stvx v22,r12,r0
|
|
|
-_savevr_23: addi r12,r0,-144
|
|
|
- stvx v23,r12,r0
|
|
|
-_savevr_24: addi r12,r0,-128
|
|
|
- stvx v24,r12,r0
|
|
|
-_savevr_25: addi r12,r0,-112
|
|
|
- stvx v25,r12,r0
|
|
|
-_savevr_26: addi r12,r0,-96
|
|
|
- stvx v26,r12,r0
|
|
|
-_savevr_27: addi r12,r0,-80
|
|
|
- stvx v27,r12,r0
|
|
|
-_savevr_28: addi r12,r0,-64
|
|
|
- stvx v28,r12,r0
|
|
|
-_savevr_29: addi r12,r0,-48
|
|
|
- stvx v29,r12,r0
|
|
|
-_savevr_30: addi r12,r0,-32
|
|
|
- stvx v30,r12,r0
|
|
|
-_savevr_31: addi r12,r0,-16
|
|
|
- stvx v31,r12,r0
|
|
|
- blr
|
|
|
-*)
|
|
|
-// The _restvr_M routines restore the vector registers from vM to v31. When the
|
|
|
-// routine is called, r0 must point to the word just beyound the end of the
|
|
|
-// vector register save area. On return the value of r0 is unchanged while r12
|
|
|
-// may be modified.
|
|
|
-(* commented out: GAS does not understand VMX opcodes?
|
|
|
-_restvr_20: addi r12,r0,-192
|
|
|
- lvx v20,r12,r0
|
|
|
-_restvr_21: addi r12,r0,-176
|
|
|
- lvx v21,r12,r0
|
|
|
-_restvr_22: addi r12,r0,-160
|
|
|
- lvx v22,r12,r0
|
|
|
-_restvr_23: addi r12,r0,-144
|
|
|
- lvx v23,r12,r0
|
|
|
-_restvr_24: addi r12,r0,-128
|
|
|
- lvx v24,r12,r0
|
|
|
-_restvr_25: addi r12,r0,-112
|
|
|
- lvx v25,r12,r0
|
|
|
-_restvr_26: addi r12,r0,-96
|
|
|
- lvx v26,r12,r0
|
|
|
-_restvr_27: addi r12,r0,-80
|
|
|
- lvx v27,r12,r0
|
|
|
-_restvr_28: addi r12,r0,-64
|
|
|
- lvx v28,r12,r0
|
|
|
-_restvr_29: addi r12,r0,-48
|
|
|
- lvx v29,r12,r0
|
|
|
-_restvr_30: addi r12,r0,-32
|
|
|
- lvx v30,r12,r0
|
|
|
-_restvr_31: addi r12,r0,-16
|
|
|
- lvx v31,r12,r0
|
|
|
- blr
|
|
|
-*)
|
|
|
-end;
|
|
|
-
|
|
|
-
|
|
|
{****************************************************************************
|
|
|
Move / Fill
|
|
|
****************************************************************************}
|
|
@@ -451,27 +88,22 @@ begin
|
|
|
v := 0;
|
|
|
{ aligned? }
|
|
|
if (PtrUInt(@x) mod sizeof(PtrUInt))<>0 then
|
|
|
- begin
|
|
|
for i:=0 to count-1 do
|
|
|
- bytearray(x)[i]:=value;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- v:=(value shl 8) or (value and $FF);
|
|
|
- v:=(v shl 16) or (v and $ffff);
|
|
|
- for i:=0 to (count div 4)-1 do
|
|
|
- longintarray(x)[i]:=v;
|
|
|
- for i:=(count div 4)*4 to count-1 do
|
|
|
- bytearray(x)[i]:=value;
|
|
|
- end;
|
|
|
+ bytearray(x)[i]:=value
|
|
|
+ else begin
|
|
|
+ v:=(value shl 8) or (value and $FF);
|
|
|
+ v:=(v shl 16) or (v and $ffff);
|
|
|
+ for i:=0 to (count div 4)-1 do
|
|
|
+ longintarray(x)[i]:=v;
|
|
|
+ for i:=(count div 4)*4 to count-1 do
|
|
|
+ bytearray(x)[i]:=value;
|
|
|
+ end;
|
|
|
end;
|
|
|
{$endif FPC_SYSTEM_HAS_FILLCHAR}
|
|
|
|
|
|
-
|
|
|
{$ifndef FPC_SYSTEM_HAS_FILLDWORD}
|
|
|
{$define FPC_SYSTEM_HAS_FILLDWORD}
|
|
|
-procedure filldword(var x;count : SizeInt;value : dword);
|
|
|
-assembler; nostackframe;
|
|
|
+procedure filldword(var x;count : SizeInt;value : dword); assembler; nostackframe;
|
|
|
asm
|
|
|
cmpdi cr0,r4,0
|
|
|
mtctr r4
|
|
@@ -787,7 +419,7 @@ asm
|
|
|
.Lcopys2loop:
|
|
|
lbzu r0,1(r5)
|
|
|
stbu r0,1(r9)
|
|
|
- bdnz .Lcopys2loop
|
|
|
+ bdnz .Lcopys2loop
|
|
|
.LconcatDone:
|
|
|
end;
|
|
|
{$endif FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
|
|
@@ -840,8 +472,8 @@ end;
|
|
|
(*
|
|
|
{$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
|
|
|
function fpc_shortstr_compare(const dstr, sstr:shortstring): SizeInt; [public,alias:'FPC_SHORTSTR_COMPARE']; compilerproc;
|
|
|
-assembler;
|
|
|
-{ TODO: improve, because the main compare loop does an unaligned access everytime.. :(
|
|
|
+assembler;
|
|
|
+{ TODO: improve, because the main compare loop does an unaligned access everytime.. :(
|
|
|
TODO: needs some additional opcodes not yet known to the compiler :( }
|
|
|
asm
|
|
|
{ load length sstr }
|
|
@@ -857,7 +489,7 @@ asm
|
|
|
|
|
|
{ first compare qwords (length/4) }
|
|
|
srdi. r5,r9,3
|
|
|
- { keep length mod 8 for the ends; note that the value in r9 <= 255
|
|
|
+ { keep length mod 8 for the ends; note that the value in r9 <= 255
|
|
|
so we can use rlwinm safely }
|
|
|
rlwinm r9,r9,0,29,31
|
|
|
{ already check whether length mod 8 = 0 }
|