* use BLX instead of "mov r14, r15; mov r15, reg" for a_call_reg on ARMv6

and above, so this also works when calling thumb code (should actually
    also be done for ARMv5T, but we don't have a monicker for that yet)
  * use BX instead of "mov r15, r14" for simple returns from subroutines
    on ARMv6+ to support returning to thumb code from ARM code (idem)

git-svn-id: trunk@14332 -
This commit is contained in:
Jonas Maebe 2009-12-04 22:38:50 +00:00
parent fa42b022d2
commit fbebd87593
5 changed files with 95 additions and 17 deletions

View File

@ -527,8 +527,14 @@ unit cgcpu;
procedure tcgarm.a_call_reg(list : TAsmList;reg: tregister);
begin
list.concat(taicpu.op_reg_reg(A_MOV,NR_R14,NR_PC));
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,reg));
{ check not really correct: should only be used for non-Thumb cpus }
if (current_settings.cputype<cpu_armv6) then
begin
list.concat(taicpu.op_reg_reg(A_MOV,NR_R14,NR_PC));
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,reg));
end
else
list.concat(taicpu.op_reg(A_BLX, reg));
{
the compiler does not properly set this flag anymore in pass 1, and
for now we only need it after pass 2 (I hope) (JM)
@ -543,8 +549,7 @@ unit cgcpu;
begin
a_reg_alloc(list,NR_R12);
a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,NR_R12);
list.concat(taicpu.op_reg_reg(A_MOV,NR_R14,NR_PC));
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R12));
a_call_reg(list,NR_R12);
a_reg_dealloc(list,NR_R12);
include(current_procinfo.flags,pi_do_call);
end;
@ -1653,7 +1658,12 @@ unit cgcpu;
end;
if regs=[] then
list.concat(taicpu.op_reg_reg(A_MOV,NR_R15,NR_R14))
begin
if (current_settings.cputype<cpu_armv6) then
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R14))
else
list.concat(taicpu.op_reg(A_BX,NR_R14))
end
else
begin
reference_reset(ref,4);
@ -1670,8 +1680,10 @@ unit cgcpu;
list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,R_INTREGISTER,R_SUBWHOLE,regs),PF_EA));
end;
end
else if (current_settings.cputype<cpu_armv6) then
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R14))
else
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R14));
list.concat(taicpu.op_reg(A_BX,NR_R14))
end;

View File

@ -137,7 +137,11 @@ Procedure FillChar(var x;count:longint;value:byte);assembler;nostackframe;
asm
// less than 0?
cmp r1,#0
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
movlt pc,lr
{$else}
bxlt lr
{$endif}
mov r3,r0
cmp r1,#8 // at least 8 bytes to do?
blt .LFillchar2
@ -168,7 +172,11 @@ asm
bge .LFillchar1
.LFillchar2:
movs r1,r1 // anything left?
moveq pc,lr
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
moveq pc,lr
{$else}
bxeq lr
{$endif}
rsb r1,r1,#7
add pc,pc,r1,lsl #2
mov r0,r0
@ -179,7 +187,11 @@ asm
strb r2,[r3],#1
strb r2,[r3],#1
strb r2,[r3],#1
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc,lr
{$else}
bx lr
{$endif}
end;
{$endif FPC_SYSTEM_HAS_FILLCHAR}
@ -191,7 +203,11 @@ asm
pld [r1]
// count <=0 ?
cmp r2,#0
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
movle pc,lr
{$else}
bxle lr
{$endif}
// overlap?
cmp r1,r0
bls .Lnooverlap
@ -204,7 +220,11 @@ asm
ldrb r3,[r0,r2]
strb r3,[r1,r2]
bne .Loverlapped
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc,lr
{$else}
bx lr
{$endif}
.Lnooverlap:
// less then 16 bytes to copy?
cmp r2,#8
@ -247,20 +267,32 @@ asm
str r3,[r1],#4
bcs .Ldwordloop
cmp r2,#0
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
moveq pc,lr
{$else}
bxeq lr
{$endif}
.Lbyteloop:
subs r2,r2,#1
ldrb r3,[r0],#1
strb r3,[r1],#1
bne .Lbyteloop
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc,lr
{$else}
bx lr
{$endif}
end;
procedure Move_blended(const source;var dest;count:longint);assembler;nostackframe;
asm
// count <=0 ?
cmp r2,#0
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
movle pc,lr
{$else}
bxle lr
{$endif}
// overlap?
cmp r1,r0
bls .Lnooverlap
@ -273,7 +305,11 @@ asm
ldrb r3,[r0,r2]
strb r3,[r1,r2]
bne .Loverlapped
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc,lr
{$else}
bx lr
{$endif}
.Lnooverlap:
// less then 16 bytes to copy?
cmp r2,#8
@ -311,13 +347,21 @@ asm
str r3,[r1],#4
bcs .Ldwordloop
cmp r2,#0
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
moveq pc,lr
{$else}
bxeq lr
{$endif}
.Lbyteloop:
subs r2,r2,#1
ldrb r3,[r0],#1
strb r3,[r1],#1
bne .Lbyteloop
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc,lr
{$else}
bx lr
{$endif}
end;
@ -492,7 +536,11 @@ asm
terminating 0, due to the known carry flag sbc can do this.*)
sbc r0,r1,r0
.Ldone:
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc,lr
{$else}
bx lr
{$endif}
.L01010101:
.long 0x01010101
end;
@ -512,7 +560,7 @@ asm
cmp r2, #0
bne .Lloop
mov r0, r1
mov pc, lr
bx lr
{$else}
// lock
ldr r3, .Lfpc_system_lock
@ -528,7 +576,7 @@ asm
mov r0, r1
// unlock and return
str r2, [r3]
mov pc, lr
bx lr
.Lfpc_system_lock:
.long fpc_system_lock
@ -546,7 +594,7 @@ asm
cmp r2, #0
bne .Lloop
mov r0, r1
mov pc, lr
bx lr
{$else}
// lock
ldr r3, .Lfpc_system_lock
@ -562,7 +610,7 @@ asm
mov r0, r1
// unlock and return
str r2, [r3]
mov pc, lr
bx lr
.Lfpc_system_lock:
.long fpc_system_lock
@ -580,7 +628,7 @@ asm
cmp r3, #0
bne .Lloop
mov r0, r2
mov pc, lr
bx lr
{$else}
swp r1, r1, [r0]
mov r0,r1
@ -597,7 +645,7 @@ asm
cmp r3, #0
bne .Lloop
mov r0, r2
mov pc, lr
bx lr
{$else}
// lock
ldr r3, .Lfpc_system_lock
@ -614,7 +662,7 @@ asm
// unlock and return
mov r2, #0
str r2, [r3]
mov pc, lr
bx lr
.Lfpc_system_lock:
.long fpc_system_lock
@ -633,7 +681,7 @@ asm
cmp r12, #0
bne .Lloop
mov r0, r3
mov pc, lr
bx lr
{$else}
// lock
ldr r12, .Lfpc_system_lock
@ -650,7 +698,7 @@ asm
// unlock and return
mov r3, #0
str r3, [r12]
mov pc, lr
bx lr
.Lfpc_system_lock:
.long fpc_system_lock

View File

@ -107,12 +107,20 @@ asm
.Ldiv_next:
bcs .Ldiv_loop
mov r0, r3
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc, lr
{$else}
bx lr
{$endif}
.Ldiv_by_0:
mov r0, #200
mov r1, r11
bl handleerrorframe
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc, lr
{$else}
bx lr
{$endif}
{$endif}
{$else}
mov r3, #0
@ -167,12 +175,20 @@ asm
.Ldiv_next:
bcs .Ldiv_loop
mov r0, r3
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc, lr
{$else}
bx lr
{$endif}
.Ldiv_by_0:
mov r0, #200
mov r1, r11
bl handleerrorframe
{$if defined(cpuarmv3) or defined(cpuarmv4) or defined(cpuarmv5)}
mov pc, lr
{$else}
bx lr
{$endif}
{$endif}
end;

View File

@ -307,6 +307,7 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
begin
cw:=VFP_GetCW and not(_VFP_ENABLE_ALL);
{$ifndef darwin}
if exInvalidOp in Mask then
cw:=cw or _VFP_ENABLE_IM;
@ -324,6 +325,7 @@ function SetExceptionMask(const Mask: TFPUExceptionMask): TFPUExceptionMask;
if exPrecision in Mask then
cw:=cw or _VFP_ENABLE_PM;
{$endif}
VFP_SetCW(cw);
result:=Mask;

View File

@ -34,7 +34,7 @@ function setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_SETJM
{$else}
stmia r0,{v1-v6, sl, fp, sp, lr}
mov r0,#0
mov pc,lr
bx lr
{$endif}
end;