* intial armv6m support, it is not working yet, constant pool insertation and conditional branch fixup is not working yet

git-svn-id: trunk@23682 -
This commit is contained in:
florian 2013-03-03 12:20:10 +00:00
parent dce8094a12
commit 1eeeb309c7
26 changed files with 1190 additions and 186 deletions

1
.gitattributes vendored
View File

@ -7436,6 +7436,7 @@ rtl/arm/setjump.inc svneol=native#text/plain
rtl/arm/setjumph.inc svneol=native#text/plain
rtl/arm/strings.inc svneol=native#text/plain
rtl/arm/stringss.inc svneol=native#text/plain
rtl/arm/thumb.inc svneol=native#text/plain
rtl/arm/thumb2.inc svneol=native#text/plain
rtl/atari/os.inc svneol=native#text/plain
rtl/atari/prt0.as svneol=native#text/plain

View File

@ -861,12 +861,22 @@ implementation
l : tasmlabel;
doinsert,
removeref : boolean;
multiplier : byte;
begin
curdata:=TAsmList.create;
lastinspos:=-1;
curinspos:=0;
extradataoffset:=0;
limit:=1016;
if current_settings.cputype in cpu_thumb then
begin
multiplier:=2;
limit:=504;
end
else
begin
limit:=1016;
multiplier:=1;
end;
curtai:=tai(list.first);
doinsert:=false;
while assigned(curtai) do
@ -898,16 +908,16 @@ implementation
ait_const:
begin
if (tai_const(hp).consttype=aitconst_64bit) then
inc(extradataoffset);
inc(extradataoffset,multiplier);
end;
ait_comp_64bit,
ait_real_64bit:
begin
inc(extradataoffset);
inc(extradataoffset,multiplier);
end;
ait_real_80bit:
begin
inc(extradataoffset,2);
inc(extradataoffset,2*multiplier);
end;
end;
if (hp.typ=ait_const) then
@ -947,32 +957,32 @@ implementation
end;
end;
end;
inc(curinspos);
inc(curinspos,multiplier);
end;
ait_align:
begin
{ code is always 4 byte aligned, so we don't have to take care of .align 2 which would
requires also incrementing curinspos by 1 }
inc(curinspos,(tai_align(curtai).aligntype div 4));
inc(curinspos,(tai_align(curtai).aligntype div 4)*multiplier);
end;
ait_const:
begin
inc(curinspos);
inc(curinspos,multiplier);
if (tai_const(curtai).consttype=aitconst_64bit) then
inc(curinspos);
inc(curinspos,multiplier);
end;
ait_real_32bit:
begin
inc(curinspos);
inc(curinspos,multiplier);
end;
ait_comp_64bit,
ait_real_64bit:
begin
inc(curinspos,2);
inc(curinspos,2*multiplier);
end;
ait_real_80bit:
begin
inc(curinspos,3);
inc(curinspos,3*multiplier);
end;
end;
{ special case for case jump tables }
@ -982,14 +992,14 @@ implementation
(taicpu(hp).oper[0]^.typ=top_reg) and
(taicpu(hp).oper[0]^.reg=NR_PC) then
begin
penalty:=1;
penalty:=1*multiplier;
hp:=tai(hp.next);
{ skip register allocations and comments inserted by the optimizer }
while assigned(hp) and (hp.typ in [ait_comment,ait_regalloc]) do
hp:=tai(hp.next);
while assigned(hp) and (hp.typ=ait_const) do
begin
inc(penalty);
inc(penalty,multiplier);
hp:=tai(hp.next);
end;
end
@ -1023,10 +1033,19 @@ implementation
begin
lastinspos:=-1;
extradataoffset:=0;
limit:=1016;
if current_settings.cputype in cpu_thumb then
limit:=508
else
limit:=1016;
doinsert:=false;
hp:=tai(curtai.next);
current_asmdata.getjumplabel(l);
{ align thumb in thumb .text section to 4 bytes }
if not(curdata.empty) and (current_settings.cputype in cpu_thumb) then
curdata.Insert(tai_align.Create(4));
curdata.insert(taicpu.op_sym(A_B,l));
curdata.concat(tai_label.create(l));
list.insertlistafter(curtai,curdata);
@ -1035,6 +1054,9 @@ implementation
else
curtai:=tai(curtai.next);
end;
{ align thumb in thumb .text section to 4 bytes }
if not(curdata.empty) and (current_settings.cputype in cpu_thumb) then
curdata.Insert(tai_align.Create(4));
list.concatlist(curdata);
curdata.free;
end;

View File

@ -68,6 +68,7 @@ unit agarmgas;
'armv6k',
'armv6t2',
'armv6z',
'armv6-m',
'armv7',
'armv7-a',
'armv7-r',

View File

@ -85,6 +85,7 @@ Implementation
function CanBeCond(p : tai) : boolean;
begin
result:=
not(current_settings.cputype in cpu_thumb) and
(p.typ=ait_instruction) and
(taicpu(p).condition=C_None) and
((taicpu(p).opcode<A_IT) or (taicpu(p).opcode>A_ITTTT)) and
@ -1666,7 +1667,8 @@ Implementation
begin
case taicpu(p).opcode Of
A_B:
if taicpu(p).condition<>C_None then
if (taicpu(p).condition<>C_None) and
not(current_settings.cputype in cpu_thumb) then
begin
{ check for
Bxx xxx

View File

@ -327,5 +327,6 @@
'vsqrt',
'vstm',
'vstr',
'vsub'
'vsub',
'neg'
);

View File

@ -327,5 +327,6 @@ attsufNONE,
attsufNONE,
attsufNONE,
attsufNONE,
attsufNONE,
attsufNONE
);

View File

@ -786,4 +786,9 @@ reg32,reg32,reg32,reg32 \x16\x00\x80\x90 ARM7
[VSQRT]
[VSTM]
[VSTR]
[VSUB]
[VSUB]
; Thumb armv6-m (gcc)
[NEG]

View File

@ -327,5 +327,6 @@ A_VPUSH,
A_VSQRT,
A_VSTM,
A_VSTR,
A_VSUB
A_VSUB,
A_NEG
);

File diff suppressed because it is too large Load Diff

View File

@ -363,7 +363,10 @@ unit cpubase;
function is_pc(const r : tregister) : boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
function is_thumb_imm(d : aint) : boolean; { Doesn't handle ROR_C detection }
function is_thumb_imm(d: aint): boolean;
{ Returns true if d is a valid constant for thumb 32 bit,
doesn't handle ROR_C detection }
function is_thumb32_imm(d : aint) : boolean;
function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword):boolean;
function dwarf_reg(r:tregister):shortint;
@ -549,7 +552,14 @@ unit cpubase;
result:=false;
end;
function is_thumb_imm(d: aint): boolean;
begin
result:=(d and $FF) = d;
end;
function is_thumb32_imm(d: aint): boolean;
var
t : aint;
i : longint;
@ -586,6 +596,7 @@ unit cpubase;
end;
end;
function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword) : boolean;
var
d, i, i2: Dword;

View File

@ -43,6 +43,7 @@ Type
cpu_armv6k,
cpu_armv6t2,
cpu_armv6z,
cpu_armv6m,
cpu_armv7,
cpu_armv7a,
cpu_armv7r,
@ -52,7 +53,7 @@ Type
Const
cpu_arm = [cpu_none,cpu_armv3,cpu_armv4,cpu_armv4t,cpu_armv5];
cpu_thumb = [];
cpu_thumb = [cpu_armv6m];
cpu_thumb2 = [cpu_armv7m];
Type
@ -243,6 +244,7 @@ Const
'ARMV6K',
'ARMV6T2',
'ARMV6Z',
'ARMV6M',
'ARMV7',
'ARMV7A',
'ARMV7R',
@ -1096,6 +1098,7 @@ Const
{ cpu_armv6k } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
{ cpu_armv6t2 } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX],
{ cpu_armv6z } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_LDREX],
{ cpu_armv6m } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_REV],
{ the identifier armv7 is should not be used, it is considered being equal to armv7a }
{ cpu_armv7 } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB],
{ cpu_armv7a } [CPUARM_HAS_BX,CPUARM_HAS_BLX,CPUARM_HAS_BLX_LABEL,CPUARM_HAS_CLZ,CPUARM_HAS_EDSP,CPUARM_HAS_REV,CPUARM_HAS_RBIT,CPUARM_HAS_LDREX,CPUARM_HAS_DMB],

View File

@ -143,15 +143,15 @@ unit cpupi;
procedure tarmprocinfo.init_framepointer;
begin
if not(target_info.system in systems_darwin) then
begin
RS_FRAME_POINTER_REG:=RS_R11;
NR_FRAME_POINTER_REG:=NR_R11;
end
else
if (target_info.system in systems_darwin) or (current_settings.cputype in cpu_thumb) then
begin
RS_FRAME_POINTER_REG:=RS_R7;
NR_FRAME_POINTER_REG:=NR_R7;
end
else
begin
RS_FRAME_POINTER_REG:=RS_R11;
NR_FRAME_POINTER_REG:=NR_R11;
end;
end;

View File

@ -406,7 +406,11 @@ interface
hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
dummyreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,right.location.register64.reglo,right.location.register64.reghi),PF_S));
if current_settings.cputype in cpu_thumb then
cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,right.location.register64.reglo,right.location.register64.reghi,dummyreg)
else
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,right.location.register64.reglo,right.location.register64.reghi),PF_S));
end
else if (nodetype in [equaln,unequaln]) and
(right.nodetype=ordconstn) and (tordconstnode(right).value=0) then
@ -417,7 +421,11 @@ interface
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
dummyreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,left.location.register64.reglo,left.location.register64.reghi),PF_S));
if current_settings.cputype in cpu_thumb then
cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reglo,left.location.register64.reghi,dummyreg)
else
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_ORR,dummyreg,left.location.register64.reglo,left.location.register64.reghi),PF_S));
end
else
begin
@ -431,7 +439,7 @@ interface
location.resflags:=getresflags(unsigned);
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register64.reghi,right.location.register64.reghi));
if current_settings.cputype in cpu_thumb2 then
if current_settings.cputype in (cpu_thumb+cpu_thumb2) then
begin
current_asmdata.getjumplabel(l);
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,l);
@ -599,7 +607,8 @@ interface
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
if right.location.loc = LOC_CONSTANT then
begin
if is_shifter_const(right.location.value,b) then
if (not(current_settings.cputype in cpu_thumb) and is_shifter_const(right.location.value,b)) or
((current_settings.cputype in cpu_thumb) and is_thumb_imm(right.location.value)) then
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_CMP,left.location.register,right.location.value))
else
begin

View File

@ -323,16 +323,16 @@ implementation
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hregister);
href:=left.location.reference;
inc(href.offset,4);
tcgarm(cg).cgsetflags:=true;
tbasecgarm(cg).cgsetflags:=true;
cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,href,hregister);
tcgarm(cg).cgsetflags:=false;
tbasecgarm(cg).cgsetflags:=false;
end
else
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
tcgarm(cg).cgsetflags:=true;
tbasecgarm(cg).cgsetflags:=true;
cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
tcgarm(cg).cgsetflags:=false;
tbasecgarm(cg).cgsetflags:=false;
end;
end;
LOC_FLAGS :
@ -345,15 +345,15 @@ implementation
begin
hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.register64.reglo,hregister);
tcgarm(cg).cgsetflags:=true;
tbasecgarm(cg).cgsetflags:=true;
cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,hregister);
tcgarm(cg).cgsetflags:=false;
tbasecgarm(cg).cgsetflags:=false;
end
else
begin
tcgarm(cg).cgsetflags:=true;
tbasecgarm(cg).cgsetflags:=true;
cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
tcgarm(cg).cgsetflags:=false;
tbasecgarm(cg).cgsetflags:=false;
end;
end;
LOC_JUMP :
@ -366,9 +366,9 @@ implementation
cg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,0,hregister);
cg.a_label(current_asmdata.CurrAsmList,hlabel);
tcgarm(cg).cgsetflags:=true;
tbasecgarm(cg).cgsetflags:=true;
cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_INT,hregister,hregister);
tcgarm(cg).cgsetflags:=false;
tbasecgarm(cg).cgsetflags:=false;
end;
else
internalerror(200311301);

View File

@ -135,18 +135,20 @@ implementation
begin
helper1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
helper2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
shifterop_reset(so);
so.shiftmode:=SM_ASR;
so.shiftimm:=31;
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_MOV,helper1,numerator,so));
shifterop_reset(so);
so.shiftmode:=SM_LSR;
so.shiftimm:=32-power;
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,helper2,numerator,helper1,so));
shifterop_reset(so);
so.shiftmode:=SM_ASR;
so.shiftimm:=power;
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_shifterop(A_MOV,resultreg,helper2,so));
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,31,numerator,helper1);
if current_settings.cputype in cpu_thumb then
begin
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,32-power,helper1);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_ADD,helper2,numerator,helper1));
end
else
begin
shifterop_reset(so);
so.shiftmode:=SM_LSR;
so.shiftimm:=32-power;
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,helper2,numerator,helper1,so));
end;
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SAR,OS_INT,power,helper2,resultreg);
end
else
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHR,OS_INT,power,numerator,resultreg)
@ -415,7 +417,7 @@ implementation
function tarmshlshrnode.first_shlshr64bitint: tnode;
begin
if (current_settings.cputype in cpu_thumb2) then
if (current_settings.cputype in cpu_thumb+cpu_thumb2) then
result:=inherited
else
result := nil;
@ -490,7 +492,7 @@ implementation
end;
begin
if (current_settings.cputype in cpu_thumb2) then
if (current_settings.cputype in cpu_thumb+cpu_thumb2) then
begin
inherited;
exit;

View File

@ -37,7 +37,8 @@ interface
implementation
uses
cutils,verbose,aasmdata,aasmcpu,cgobj;
cutils,verbose,globals,aasmdata,aasmcpu,cgobj,
cpuinfo;
{*****************************************************************************
TARMVECNODE
@ -49,6 +50,7 @@ implementation
hl : longint;
begin
if ((location.reference.base=NR_NO) and (location.reference.index=NR_NO)) or
(current_settings.cputype in cpu_thumb) or
{ simple constant? }
(l=1) or ispowerof2(l,hl) or ispowerof2(l+1,hl) or ispowerof2(l-1,hl) then
inherited update_reference_reg_mul(maybe_const_reg,l)

View File

@ -240,11 +240,11 @@ implementation
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, opcgsize, OC_EQ,0,hregister,blocklabel(t^.blockid))
else
begin
tcgarm(cg).cgsetflags:=true;
tbasecgarm(cg).cgsetflags:=true;
{ use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
then genlinearlist wouldn't be used }
cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SUB, OS_32, aint(int64(t^._low-last)), hregister);
tcgarm(cg).cgsetflags:=false;
tbasecgarm(cg).cgsetflags:=false;
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_EQ,blocklabel(t^.blockid));
end;
last:=t^._low;
@ -260,11 +260,11 @@ implementation
{ have we to ajust the first value ? }
if (t^._low>get_min_value(left.resultdef)) or (get_min_value(left.resultdef)<>0) then
begin
tcgarm(cg).cgsetflags:=true;
tbasecgarm(cg).cgsetflags:=true;
{ use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
then genlinearlist wouldn't be use }
cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SUB, OS_32, aint(int64(t^._low)), hregister);
tcgarm(cg).cgsetflags:=false;
tbasecgarm(cg).cgsetflags:=false;
end;
end
else
@ -273,22 +273,22 @@ implementation
{ present label then the lower limit can be checked }
{ immediately. else check the range in between: }
tcgarm(cg).cgsetflags:=true;
tbasecgarm(cg).cgsetflags:=true;
{ use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
then genlinearlist wouldn't be use }
cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_SUB, OS_32, aint(int64(t^._low-last)), hregister);
tcgarm(cg).cgsetflags:=false;
tbasecgarm(cg).cgsetflags:=false;
{ no jump necessary here if the new range starts at }
{ at the value following the previous one }
if ((t^._low-last) <> 1) or
(not lastrange) then
cg.a_jmp_flags(current_asmdata.CurrAsmList,cond_lt,elselabel);
end;
tcgarm(cg).cgsetflags:=true;
tbasecgarm(cg).cgsetflags:=true;
{ use OS_32 here to avoid uncessary sign extensions, at this place hregister will never be negative, because
then genlinearlist wouldn't be use }
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SUB,OS_32,aint(int64(t^._high-t^._low)),hregister);
tcgarm(cg).cgsetflags:=false;
tbasecgarm(cg).cgsetflags:=false;
cg.a_jmp_flags(current_asmdata.CurrAsmList,cond_le,blocklabel(t^.blockid));
last:=t^._high;

View File

@ -1702,7 +1702,6 @@ implementation
procedure Tcg.a_op_const_reg_reg(list:TAsmList;op:Topcg;size:Tcgsize;
a:tcgint;src,dst:Tregister);
begin
a_load_reg_reg(list,size,size,src,dst);
a_op_const_reg(list,op,size,a,dst);

View File

@ -156,7 +156,7 @@ implementation
lab_real := TAsmLabel(entry^.Data); // is it needed anymore?
{ :-(, we must generate a new entry }
if not assigned(lab_real) then
if not(assigned(lab_real)) then
begin
current_asmdata.getdatalabel(lastlabel);
entry^.Data:=lastlabel;

View File

@ -3250,6 +3250,13 @@ if (target_info.abi = abi_eabihf) then
{$endif CPUARMV6}
end;
if init_settings.cputype in cpu_thumb then
begin
def_system_macro('CPUTHUMB');
if not option.FPUSetExplicitly then
init_settings.fputype:=fpu_soft;
end;
if init_settings.cputype in cpu_thumb2 then
def_system_macro('CPUTHUMB2');
{$endif arm}

View File

@ -13,6 +13,7 @@
**********************************************************************}
{$ifndef CPUTHUMB}
{$define FPC_SYSTEM_HAS_MUL_QWORD}
function fpc_mul_qword(f1,f2 : qword;checkoverflow : longbool) : qword;assembler;nostackframe;[public,alias: 'FPC_MUL_QWORD']; compilerproc;
asm
@ -61,5 +62,5 @@ asm
.Lexit:
ldmfd sp!,{r4,r5,r6,r15}
end;
{$endif CPUTHUMB}

View File

@ -27,13 +27,29 @@ function fpc_setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_S
{$endif}
{$endif}
{$if defined(CPUCORTEXM3) or defined(CPUARMV7M)}
{$if defined(CPUTHUMB2)}
stmia r0!, {v1-v6, sl, fp}
mov r2, sp
mov r2, sp
stmia r0!, {r2, lr}
mov r0,#0
mov pc,lr
{$elseif defined(CPUTHUMB)}
stmia r0!,{v1-v4}
mov r1,v5
str r1,[r0]
mov r1,v6
str r1,[r0,#4]
mov r1,sl
str r1,[r0,#8]
mov r1,fp
str r1,[r0,#12]
mov r1,sp
str r1,[r0,#16]
mov r1,lr
str r1,[r0,#20]
mov r0,#0
bx lr
{$else}
stmia r0,{v1-v6, sl, fp, sp, lr}
mov r0,#0
@ -44,7 +60,7 @@ function fpc_setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_S
procedure fpc_longjmp(var S : jmp_buf;value : longint);assembler;[Public, alias : 'FPC_LONGJMP']; compilerproc;
asm
{$if defined(CPUCORTEXM3) or defined(CPUARMV7M)}
{$if defined(CPUTHUMB2)}
mov ip, r0
movs r0, r1
it eq
@ -56,6 +72,27 @@ procedure fpc_longjmp(var S : jmp_buf;value : longint);assembler;[Public, alias
ldr sp, [ip]
add ip, ip, #4
ldr pc, [ip]
{$elseif defined(CPUTHUMB)}
mov r3, r0
movs r0, r1
bne .L1
mov r0, #1
.L1:
ldmia r3!,{v1-v4}
ldr r2,[r3]
mov v5,r2
ldr r2,[r3,#4]
mov v6,r2
ldr r2,[r3,#8]
mov sl,r2
ldr r2,[r3,#12]
mov fp,r2
ldr r2,[r3,#16]
mov sp,r2
ldr r2,[r3,#20]
mov pc,r2
{$else}
mov ip, r0
movs r0, r1

96
rtl/arm/thumb.inc Normal file
View File

@ -0,0 +1,96 @@
{
This file is part of the Free Pascal run time library.
Copyright (c) 2013 by the Free Pascal development team.
Processor dependent implementation for the system unit for
ARM Thumb
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{$define FPC_SYSTEM_HAS_SYSINITFPU}
Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
softfloat_exception_mask:=float_flag_underflow or float_flag_inexact or float_flag_denormal;
end;
procedure fpc_cpuinit;
begin
SysInitFPU;
end;
{$define FPC_SYSTEM_HAS_SYSRESETFPU}
Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
begin
softfloat_exception_flags:=0;
end;
{$IFNDEF INTERNAL_BACKTRACE}
{$define FPC_SYSTEM_HAS_GET_FRAME}
function get_frame:pointer;assembler;nostackframe;
asm
end;
{$ENDIF not INTERNAL_BACKTRACE}
{$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;assembler;
asm
end;
{$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;assembler;
asm
end;
{$define FPC_SYSTEM_HAS_SPTR}
Function Sptr : pointer;assembler;
asm
end;
function InterLockedDecrement (var Target: longint) : longint;
begin
dec(Target);
Result:=Target;
end;
function InterLockedIncrement (var Target: longint) : longint;
begin
inc(Target);
Result:=Target;
end;
function InterLockedExchange (var Target: longint;Source : longint) : longint;
begin
Result:=Target;
Target:=Source;
end;
function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;
begin
Result:=Target;
if Target=Comperand then
Target:=NewValue;
end;
function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;
begin
Result:=Target;
inc(Target,Source);
end;

View File

@ -1,5 +1,5 @@
#
# Don't edit, this file is generated by FPCMake Version 2.0.0 [2013/01/16]
# Don't edit, this file is generated by FPCMake Version 2.0.0 [2013/02/22]
#
default: all
MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux jvm-java jvm-android
@ -269,6 +269,19 @@ ifdef CROSSCOMPILE
ifndef DARWIN2DARWIN
ifneq ($(CPU_TARGET),jvm)
BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
ifeq ($(OS_TARGET),android)
ifeq ($(CPU_TARGET),arm)
BINUTILSPREFIX=arm-linux-androideabi-
else
ifeq ($(CPU_TARGET),i386)
BINUTILSPREFIX=i686-linux-android-
else
ifeq ($(CPU_TARGET),mips)
BINUTILSPREFIX=mipsel-linux-android-
endif
endif
endif
endif
endif
endif
endif
@ -321,7 +334,7 @@ CPU_SPECIFIC_COMMON_UNITS=
ifeq ($(ARCH),arm)
CPU_SPECIFIC_COMMON_UNITS=sysutils sysconst
ifeq ($(SUBARCH),armv7m)
CPU_UNITS=lm3fury lm3tempest stm32f10x_ld stm32f10x_md stm32f10x_hd stm32f10x_xl stm32f10x_conn lpc1768 lpc1343 # thumb2_bare
CPU_UNITS=lm3fury lm3tempest stm32f10x_ld stm32f10x_md stm32f10x_hd stm32f10x_xl stm32f10x_conn lpc1343 lpc1768 # thumb2_bare
endif
ifeq ($(SUBARCH),armv4t)
CPU_UNITS=lpc21x4 at91sam7x256 sc32442b
@ -329,6 +342,9 @@ endif
ifeq ($(SUBARCH),armv4)
CPU_UNITS=lpc21x4 at91sam7x256 sc32442b
endif
ifeq ($(SUBARCH),armv6m)
CPU_UNITS=
endif
endif
ifeq ($(ARCH),avr)
CPU_UNITS=atmega128

View File

@ -62,6 +62,9 @@ endif
ifeq ($(SUBARCH),armv4)
CPU_UNITS=lpc21x4 at91sam7x256 sc32442b
endif
ifeq ($(SUBARCH),armv6m)
CPU_UNITS=
endif
endif
ifeq ($(ARCH),avr)

View File

@ -221,7 +221,11 @@ function do_isdevice(handle:thandle):boolean;forward;
{$if defined(CPUCORTEXM3) or defined(CPUARMV7M)}
{$i thumb2.inc} { Case dependent, don't change }
{$else}
{$i arm.inc} { Case dependent, don't change }
{$if defined(CPUARMV6M)}
{$i thumb.inc} { Case dependent, don't change }
{$else}
{$i arm.inc} { Case dependent, don't change }
{$endif}
{$endif}
{$define SYSPROCDEFINED}
{$endif cpuarm}