mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-04 13:47:23 +01:00
* 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:
parent
dce8094a12
commit
1eeeb309c7
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -68,6 +68,7 @@ unit agarmgas;
|
||||
'armv6k',
|
||||
'armv6t2',
|
||||
'armv6z',
|
||||
'armv6-m',
|
||||
'armv7',
|
||||
'armv7-a',
|
||||
'armv7-r',
|
||||
|
||||
@ -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
|
||||
|
||||
@ -327,5 +327,6 @@
|
||||
'vsqrt',
|
||||
'vstm',
|
||||
'vstr',
|
||||
'vsub'
|
||||
'vsub',
|
||||
'neg'
|
||||
);
|
||||
|
||||
@ -327,5 +327,6 @@ attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE,
|
||||
attsufNONE
|
||||
);
|
||||
|
||||
@ -786,4 +786,9 @@ reg32,reg32,reg32,reg32 \x16\x00\x80\x90 ARM7
|
||||
[VSQRT]
|
||||
[VSTM]
|
||||
[VSTR]
|
||||
[VSUB]
|
||||
[VSUB]
|
||||
|
||||
; Thumb armv6-m (gcc)
|
||||
[NEG]
|
||||
|
||||
|
||||
|
||||
@ -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
@ -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;
|
||||
|
||||
@ -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],
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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}
|
||||
|
||||
|
||||
@ -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
96
rtl/arm/thumb.inc
Normal 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;
|
||||
@ -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
|
||||
|
||||
@ -62,6 +62,9 @@ endif
|
||||
ifeq ($(SUBARCH),armv4)
|
||||
CPU_UNITS=lpc21x4 at91sam7x256 sc32442b
|
||||
endif
|
||||
ifeq ($(SUBARCH),armv6m)
|
||||
CPU_UNITS=
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),avr)
|
||||
|
||||
@ -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}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user