mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-02 21:58:29 +02:00
Implemented UAL syntax support in the ARM assembler reader. Can be toggled with a field for now, but not implemented yet. Still using pre-UAL syntax for now.
Switched codegeneration of VFPv2 and VFPv3 to use UAL mnemonics and syntax. Updated VFP code in RTL to use UAL syntax too. Added preliminary ELF support for ARM. Added support for linking of WinCE COFF files. Should work for with a standard ARMv4-I target. git-svn-id: branches/laksen/armiw@29247 -
This commit is contained in:
parent
d023c63ad0
commit
9e5979e8be
@ -314,7 +314,7 @@ unit agarmgas;
|
|||||||
// writeln(taicpu(hp).fileinfo.line);
|
// writeln(taicpu(hp).fileinfo.line);
|
||||||
|
|
||||||
{ LDM and STM use references as first operand but they are written like a register }
|
{ LDM and STM use references as first operand but they are written like a register }
|
||||||
if (i=0) and (op in [A_LDM,A_STM,A_FSTM,A_FLDM]) then
|
if (i=0) and (op in [A_LDM,A_STM,A_FSTM,A_FLDM,A_VSTM,A_VLDM]) then
|
||||||
begin
|
begin
|
||||||
case taicpu(hp).oper[0]^.typ of
|
case taicpu(hp).oper[0]^.typ of
|
||||||
top_ref:
|
top_ref:
|
||||||
|
@ -2353,7 +2353,7 @@ Implementation
|
|||||||
{ set of opcode which might or do write to memory }
|
{ set of opcode which might or do write to memory }
|
||||||
{ TODO : extend armins.dat to contain r/w info }
|
{ TODO : extend armins.dat to contain r/w info }
|
||||||
opcode_could_mem_write = [A_B,A_BL,A_BLX,A_BKPT,A_BX,A_STR,A_STRB,A_STRBT,
|
opcode_could_mem_write = [A_B,A_BL,A_BLX,A_BKPT,A_BX,A_STR,A_STRB,A_STRBT,
|
||||||
A_STRH,A_STRT,A_STF,A_SFM,A_STM,A_FSTS,A_FSTD];
|
A_STRH,A_STRT,A_STF,A_SFM,A_STM,A_FSTS,A_FSTD,A_VSTR,A_VSTM];
|
||||||
|
|
||||||
|
|
||||||
{ adjust the register live information when swapping the two instructions p and hp1,
|
{ adjust the register live information when swapping the two instructions p and hp1,
|
||||||
|
@ -2033,11 +2033,11 @@ unit cgcpu;
|
|||||||
ref.index:=ref.base;
|
ref.index:=ref.base;
|
||||||
ref.base:=NR_NO;
|
ref.base:=NR_NO;
|
||||||
{ FSTMX is deprecated on ARMv6 and later }
|
{ FSTMX is deprecated on ARMv6 and later }
|
||||||
if (current_settings.cputype<cpu_armv6) then
|
{if (current_settings.cputype<cpu_armv6) then
|
||||||
postfix:=PF_IAX
|
postfix:=PF_IAX
|
||||||
else
|
else
|
||||||
postfix:=PF_IAD;
|
postfix:=PF_IAD;}
|
||||||
list.concat(setoppostfix(taicpu.op_ref_regset(A_FSTM,ref,R_MMREGISTER,R_SUBFD,mmregs),postfix));
|
list.concat(taicpu.op_ref_regset(A_VSTM,ref,R_MMREGISTER,R_SUBFD,mmregs));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2134,11 +2134,11 @@ unit cgcpu;
|
|||||||
ref.index:=ref.base;
|
ref.index:=ref.base;
|
||||||
ref.base:=NR_NO;
|
ref.base:=NR_NO;
|
||||||
{ FLDMX is deprecated on ARMv6 and later }
|
{ FLDMX is deprecated on ARMv6 and later }
|
||||||
if (current_settings.cputype<cpu_armv6) then
|
{if (current_settings.cputype<cpu_armv6) then
|
||||||
mmpostfix:=PF_IAX
|
mmpostfix:=PF_IAX
|
||||||
else
|
else
|
||||||
mmpostfix:=PF_IAD;
|
mmpostfix:=PF_IAD;}
|
||||||
list.concat(setoppostfix(taicpu.op_ref_regset(A_FLDM,ref,R_MMREGISTER,R_SUBFD,mmregs),mmpostfix));
|
list.concat(taicpu.op_ref_regset(A_VLDM,ref,R_MMREGISTER,R_SUBFD,mmregs));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2912,8 +2912,8 @@ unit cgcpu;
|
|||||||
function get_scalar_mm_op(fromsize,tosize : tcgsize) : tasmop;
|
function get_scalar_mm_op(fromsize,tosize : tcgsize) : tasmop;
|
||||||
const
|
const
|
||||||
convertop : array[OS_F32..OS_F128,OS_F32..OS_F128] of tasmop = (
|
convertop : array[OS_F32..OS_F128,OS_F32..OS_F128] of tasmop = (
|
||||||
(A_FCPYS,A_FCVTSD,A_NONE,A_NONE,A_NONE),
|
(A_VMOV,A_VCVT,A_NONE,A_NONE,A_NONE),
|
||||||
(A_FCVTDS,A_FCPYD,A_NONE,A_NONE,A_NONE),
|
(A_VCVT,A_VMOV,A_NONE,A_NONE,A_NONE),
|
||||||
(A_NONE,A_NONE,A_NONE,A_NONE,A_NONE),
|
(A_NONE,A_NONE,A_NONE,A_NONE,A_NONE),
|
||||||
(A_NONE,A_NONE,A_NONE,A_NONE,A_NONE),
|
(A_NONE,A_NONE,A_NONE,A_NONE,A_NONE),
|
||||||
(A_NONE,A_NONE,A_NONE,A_NONE,A_NONE));
|
(A_NONE,A_NONE,A_NONE,A_NONE,A_NONE));
|
||||||
@ -2924,33 +2924,30 @@ unit cgcpu;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function get_scalar_mm_prefix(fromsize,tosize : tcgsize) : TOpPostfix;
|
||||||
|
const
|
||||||
|
convertop : array[OS_F32..OS_F128,OS_F32..OS_F128] of TOpPostfix = (
|
||||||
|
(PF_F32, PF_F32F64,PF_None,PF_None,PF_None),
|
||||||
|
(PF_F64F32,PF_F64, PF_None,PF_None,PF_None),
|
||||||
|
(PF_None, PF_None, PF_None,PF_None,PF_None),
|
||||||
|
(PF_None, PF_None, PF_None,PF_None,PF_None),
|
||||||
|
(PF_None, PF_None, PF_None,PF_None,PF_None));
|
||||||
|
begin
|
||||||
|
result:=convertop[fromsize,tosize];
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tbasecgarm.a_loadmm_reg_reg(list: tasmlist; fromsize,tosize: tcgsize; reg1,reg2: tregister; shuffle: pmmshuffle);
|
procedure tbasecgarm.a_loadmm_reg_reg(list: tasmlist; fromsize,tosize: tcgsize; reg1,reg2: tregister; shuffle: pmmshuffle);
|
||||||
var
|
var
|
||||||
instr: taicpu;
|
instr: taicpu;
|
||||||
begin
|
begin
|
||||||
if shuffle=nil then
|
if (shuffle=nil) or shufflescalar(shuffle) then
|
||||||
begin
|
instr:=setoppostfix(taicpu.op_reg_reg(get_scalar_mm_op(tosize,fromsize),reg2,reg1),get_scalar_mm_prefix(tosize,fromsize))
|
||||||
if fromsize=tosize then
|
|
||||||
{ needs correct size in case of spilling }
|
|
||||||
case fromsize of
|
|
||||||
OS_F32:
|
|
||||||
instr:=taicpu.op_reg_reg(A_FCPYS,reg2,reg1);
|
|
||||||
OS_F64:
|
|
||||||
instr:=taicpu.op_reg_reg(A_FCPYD,reg2,reg1);
|
|
||||||
else
|
|
||||||
internalerror(2009112405);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
internalerror(2009112406);
|
|
||||||
end
|
|
||||||
else if shufflescalar(shuffle) then
|
|
||||||
instr:=taicpu.op_reg_reg(get_scalar_mm_op(tosize,fromsize),reg2,reg1)
|
|
||||||
else
|
else
|
||||||
internalerror(2009112407);
|
internalerror(2009112407);
|
||||||
list.concat(instr);
|
list.concat(instr);
|
||||||
case instr.opcode of
|
case instr.opcode of
|
||||||
A_FCPYS,
|
A_VMOV:
|
||||||
A_FCPYD:
|
|
||||||
add_move_instruction(instr);
|
add_move_instruction(instr);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2961,7 +2958,6 @@ unit cgcpu;
|
|||||||
intreg,
|
intreg,
|
||||||
tmpmmreg : tregister;
|
tmpmmreg : tregister;
|
||||||
reg64 : tregister64;
|
reg64 : tregister64;
|
||||||
op : tasmop;
|
|
||||||
begin
|
begin
|
||||||
if assigned(shuffle) and
|
if assigned(shuffle) and
|
||||||
not(shufflescalar(shuffle)) then
|
not(shufflescalar(shuffle)) then
|
||||||
@ -3010,15 +3006,7 @@ unit cgcpu;
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
case fromsize of
|
handle_load_store(list,A_VLDR,PF_None,tmpmmreg,ref);
|
||||||
OS_F32:
|
|
||||||
op:=A_FLDS;
|
|
||||||
OS_F64:
|
|
||||||
op:=A_FLDD;
|
|
||||||
else
|
|
||||||
internalerror(2009112415);
|
|
||||||
end;
|
|
||||||
handle_load_store(list,op,PF_None,tmpmmreg,ref);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (tmpmmreg<>reg) then
|
if (tmpmmreg<>reg) then
|
||||||
@ -3031,7 +3019,6 @@ unit cgcpu;
|
|||||||
intreg,
|
intreg,
|
||||||
tmpmmreg : tregister;
|
tmpmmreg : tregister;
|
||||||
reg64 : tregister64;
|
reg64 : tregister64;
|
||||||
op : tasmop;
|
|
||||||
begin
|
begin
|
||||||
if assigned(shuffle) and
|
if assigned(shuffle) and
|
||||||
not(shufflescalar(shuffle)) then
|
not(shufflescalar(shuffle)) then
|
||||||
@ -3083,15 +3070,7 @@ unit cgcpu;
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
case fromsize of
|
handle_load_store(list,A_VSTR,PF_None,tmpmmreg,ref);
|
||||||
OS_F32:
|
|
||||||
op:=A_FSTS;
|
|
||||||
OS_F64:
|
|
||||||
op:=A_FSTD;
|
|
||||||
else
|
|
||||||
internalerror(2009112418);
|
|
||||||
end;
|
|
||||||
handle_load_store(list,op,PF_None,tmpmmreg,ref);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -3107,7 +3086,7 @@ unit cgcpu;
|
|||||||
if assigned(shuffle) and
|
if assigned(shuffle) and
|
||||||
not shufflescalar(shuffle) then
|
not shufflescalar(shuffle) then
|
||||||
internalerror(2009112516);
|
internalerror(2009112516);
|
||||||
list.concat(taicpu.op_reg_reg(A_FMSR,mmreg,intreg));
|
list.concat(taicpu.op_reg_reg(A_VMOV,mmreg,intreg));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -3122,7 +3101,7 @@ unit cgcpu;
|
|||||||
if assigned(shuffle) and
|
if assigned(shuffle) and
|
||||||
not shufflescalar(shuffle) then
|
not shufflescalar(shuffle) then
|
||||||
internalerror(2009112514);
|
internalerror(2009112514);
|
||||||
list.concat(taicpu.op_reg_reg(A_FMRS,intreg,mmreg));
|
list.concat(taicpu.op_reg_reg(A_VMOV,intreg,mmreg));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -3144,9 +3123,9 @@ unit cgcpu;
|
|||||||
a_load_const_reg(list,OS_32,0,tmpreg);
|
a_load_const_reg(list,OS_32,0,tmpreg);
|
||||||
case size of
|
case size of
|
||||||
OS_F32:
|
OS_F32:
|
||||||
list.concat(taicpu.op_reg_reg(A_FMSR,dst,tmpreg));
|
list.concat(taicpu.op_reg_reg(A_VMOV,dst,tmpreg));
|
||||||
OS_F64:
|
OS_F64:
|
||||||
list.concat(taicpu.op_reg_reg_reg(A_FMDRR,dst,tmpreg,tmpreg));
|
list.concat(taicpu.op_reg_reg_reg(A_VMOV,dst,tmpreg,tmpreg));
|
||||||
else
|
else
|
||||||
internalerror(2009112908);
|
internalerror(2009112908);
|
||||||
end;
|
end;
|
||||||
@ -3408,7 +3387,7 @@ unit cgcpu;
|
|||||||
conversions }
|
conversions }
|
||||||
if (mmsize<>OS_F64) then
|
if (mmsize<>OS_F64) then
|
||||||
internalerror(2009112405);
|
internalerror(2009112405);
|
||||||
list.concat(taicpu.op_reg_reg_reg(A_FMDRR,mmreg,intreg.reglo,intreg.reghi));
|
list.concat(taicpu.op_reg_reg_reg(A_VMOV,mmreg,intreg.reglo,intreg.reghi));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -3418,7 +3397,7 @@ unit cgcpu;
|
|||||||
conversions }
|
conversions }
|
||||||
if (mmsize<>OS_F64) then
|
if (mmsize<>OS_F64) then
|
||||||
internalerror(2009112406);
|
internalerror(2009112406);
|
||||||
list.concat(taicpu.op_reg_reg_reg(A_FMRRD,intreg.reglo,intreg.reghi,mmreg));
|
list.concat(taicpu.op_reg_reg_reg(A_VMOV,intreg.reglo,intreg.reghi,mmreg));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -5276,19 +5255,13 @@ unit cgcpu;
|
|||||||
|
|
||||||
procedure tthumb2cgarm.a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister; shuffle: pmmshuffle);
|
procedure tthumb2cgarm.a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister; shuffle: pmmshuffle);
|
||||||
begin
|
begin
|
||||||
if fromsize=OS_F32 then
|
handle_load_store(list,A_VLDR,PF_None,reg,ref);
|
||||||
handle_load_store(list,A_VLDR,PF_F32,reg,ref)
|
|
||||||
else
|
|
||||||
handle_load_store(list,A_VLDR,PF_F64,reg,ref);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tthumb2cgarm.a_loadmm_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference; shuffle: pmmshuffle);
|
procedure tthumb2cgarm.a_loadmm_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference; shuffle: pmmshuffle);
|
||||||
begin
|
begin
|
||||||
if fromsize=OS_F32 then
|
handle_load_store(list,A_VSTR,PF_None,reg,ref);
|
||||||
handle_load_store(list,A_VSTR,PF_F32,reg,ref)
|
|
||||||
else
|
|
||||||
handle_load_store(list,A_VSTR,PF_F64,reg,ref);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -325,8 +325,12 @@ implementation
|
|||||||
result:=R_ARM_ABS32;
|
result:=R_ARM_ABS32;
|
||||||
RELOC_RELATIVE:
|
RELOC_RELATIVE:
|
||||||
result:=R_ARM_REL32;
|
result:=R_ARM_REL32;
|
||||||
|
RELOC_RELATIVE_24,
|
||||||
|
RELOC_RELATIVE_24_THUMB:
|
||||||
|
result:=R_ARM_CALL;
|
||||||
else
|
else
|
||||||
result:=0;
|
result:=0;
|
||||||
|
writeln(objrel.typ);
|
||||||
InternalError(2012110602);
|
InternalError(2012110602);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -926,7 +930,23 @@ implementation
|
|||||||
loadsection: @elf_arm_loadSection;
|
loadsection: @elf_arm_loadSection;
|
||||||
);
|
);
|
||||||
|
|
||||||
|
as_arm_elf32_info : tasminfo =
|
||||||
|
(
|
||||||
|
id : as_arm_elf32;
|
||||||
|
idtxt : 'ELF';
|
||||||
|
asmbin : '';
|
||||||
|
asmcmd : '';
|
||||||
|
supported_targets : [system_arm_embedded,system_arm_darwin,
|
||||||
|
system_arm_linux,system_arm_gba,
|
||||||
|
system_arm_nds];
|
||||||
|
flags : [af_outputbinary,af_smartlink_sections,af_supports_dwarf];
|
||||||
|
labelprefix : '.L';
|
||||||
|
comment : '';
|
||||||
|
dollarsign: '$';
|
||||||
|
);
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
RegisterAssembler(as_arm_elf32_info,TElfAssembler);
|
||||||
ElfTarget:=elf_target_arm;
|
ElfTarget:=elf_target_arm;
|
||||||
ElfExeOutputClass:=TElfExeOutputARM;
|
ElfExeOutputClass:=TElfExeOutputARM;
|
||||||
|
|
||||||
|
@ -162,6 +162,7 @@ interface
|
|||||||
var
|
var
|
||||||
op : TAsmOp;
|
op : TAsmOp;
|
||||||
singleprec: boolean;
|
singleprec: boolean;
|
||||||
|
pf: TOpPostfix;
|
||||||
begin
|
begin
|
||||||
pass_left_right;
|
pass_left_right;
|
||||||
if (nf_swapped in flags) then
|
if (nf_swapped in flags) then
|
||||||
@ -210,33 +211,25 @@ interface
|
|||||||
location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
|
location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
|
||||||
|
|
||||||
singleprec:=tfloatdef(left.resultdef).floattype=s32real;
|
singleprec:=tfloatdef(left.resultdef).floattype=s32real;
|
||||||
|
if singleprec then
|
||||||
|
pf:=PF_F32
|
||||||
|
else
|
||||||
|
pf:=PF_F64;
|
||||||
case nodetype of
|
case nodetype of
|
||||||
addn :
|
addn :
|
||||||
if singleprec then
|
op:=A_VADD;
|
||||||
op:=A_FADDS
|
|
||||||
else
|
|
||||||
op:=A_FADDD;
|
|
||||||
muln :
|
muln :
|
||||||
if singleprec then
|
op:=A_VMUL;
|
||||||
op:=A_FMULS
|
|
||||||
else
|
|
||||||
op:=A_FMULD;
|
|
||||||
subn :
|
subn :
|
||||||
if singleprec then
|
op:=A_VSUB;
|
||||||
op:=A_FSUBS
|
|
||||||
else
|
|
||||||
op:=A_FSUBD;
|
|
||||||
slashn :
|
slashn :
|
||||||
if singleprec then
|
op:=A_VDIV;
|
||||||
op:=A_FDIVS
|
|
||||||
else
|
|
||||||
op:=A_FDIVD;
|
|
||||||
else
|
else
|
||||||
internalerror(2009111401);
|
internalerror(2009111401);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,
|
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(op,
|
||||||
location.register,left.location.register,right.location.register));
|
location.register,left.location.register,right.location.register),pf));
|
||||||
end;
|
end;
|
||||||
fpu_fpv4_s16:
|
fpu_fpv4_s16:
|
||||||
begin
|
begin
|
||||||
@ -275,6 +268,7 @@ interface
|
|||||||
procedure tarmaddnode.second_cmpfloat;
|
procedure tarmaddnode.second_cmpfloat;
|
||||||
var
|
var
|
||||||
op: TAsmOp;
|
op: TAsmOp;
|
||||||
|
pf: TOpPostfix;
|
||||||
begin
|
begin
|
||||||
pass_left_right;
|
pass_left_right;
|
||||||
if (nf_swapped in flags) then
|
if (nf_swapped in flags) then
|
||||||
@ -310,19 +304,20 @@ interface
|
|||||||
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
|
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
|
||||||
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
|
hlcg.location_force_mmregscalar(current_asmdata.CurrAsmList,right.location,right.resultdef,true);
|
||||||
|
|
||||||
if (tfloatdef(left.resultdef).floattype=s32real) then
|
if nodetype in [equaln,unequaln] then
|
||||||
if nodetype in [equaln,unequaln] then
|
op:=A_VCMP
|
||||||
op:=A_FCMPS
|
|
||||||
else
|
|
||||||
op:=A_FCMPES
|
|
||||||
else if nodetype in [equaln,unequaln] then
|
|
||||||
op:=A_FCMPD
|
|
||||||
else
|
else
|
||||||
op:=A_FCMPED;
|
op:=A_VCMPE;
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,
|
|
||||||
left.location.register,right.location.register));
|
if (tfloatdef(left.resultdef).floattype=s32real) then
|
||||||
|
pf:=PF_F32
|
||||||
|
else
|
||||||
|
pf:=PF_F64;
|
||||||
|
|
||||||
|
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(op,
|
||||||
|
left.location.register,right.location.register), pf));
|
||||||
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
|
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_DEFAULTFLAGS);
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_FMSTAT));
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VMRS,NR_APSR_nzcv,NR_FPSCR));
|
||||||
location.resflags:=GetFpuResFlags;
|
location.resflags:=GetFpuResFlags;
|
||||||
end;
|
end;
|
||||||
fpu_fpv4_s16:
|
fpu_fpv4_s16:
|
||||||
|
@ -170,9 +170,9 @@ implementation
|
|||||||
|
|
||||||
procedure tarmtypeconvnode.second_int_to_real;
|
procedure tarmtypeconvnode.second_int_to_real;
|
||||||
const
|
const
|
||||||
signedprec2vfpop: array[boolean,OS_F32..OS_F64] of tasmop =
|
signedprec2vfppf: array[boolean,OS_F32..OS_F64] of toppostfix =
|
||||||
((A_FUITOS,A_FUITOD),
|
((PF_F32U32,PF_F64U32),
|
||||||
(A_FSITOS,A_FSITOD));
|
(PF_F32S32,PF_F64S32));
|
||||||
var
|
var
|
||||||
instr : taicpu;
|
instr : taicpu;
|
||||||
href : treference;
|
href : treference;
|
||||||
@ -253,8 +253,9 @@ implementation
|
|||||||
location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size)
|
location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size)
|
||||||
else
|
else
|
||||||
location.register:=left.location.register;
|
location.register:=left.location.register;
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(
|
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VCVT,
|
||||||
signedprec2vfpop[signed,location.size],location.register,left.location.register));
|
location.register,left.location.register),
|
||||||
|
signedprec2vfppf[signed,location.size]));
|
||||||
end;
|
end;
|
||||||
fpu_fpv4_s16:
|
fpu_fpv4_s16:
|
||||||
begin
|
begin
|
||||||
|
@ -234,7 +234,7 @@ implementation
|
|||||||
procedure tarminlinenode.second_abs_real;
|
procedure tarminlinenode.second_abs_real;
|
||||||
var
|
var
|
||||||
singleprec: boolean;
|
singleprec: boolean;
|
||||||
op: TAsmOp;
|
pf: TOpPostfix;
|
||||||
begin
|
begin
|
||||||
load_fpu_location(singleprec);
|
load_fpu_location(singleprec);
|
||||||
case current_settings.fputype of
|
case current_settings.fputype of
|
||||||
@ -247,10 +247,10 @@ implementation
|
|||||||
fpu_vfpv3_d16:
|
fpu_vfpv3_d16:
|
||||||
begin
|
begin
|
||||||
if singleprec then
|
if singleprec then
|
||||||
op:=A_FABSS
|
pf:=PF_F32
|
||||||
else
|
else
|
||||||
op:=A_FABSD;
|
pf:=PF_F64;
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,location.register,left.location.register));
|
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register),pf));
|
||||||
end;
|
end;
|
||||||
fpu_fpv4_s16:
|
fpu_fpv4_s16:
|
||||||
current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register), PF_F32));
|
current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg(A_VABS,location.register,left.location.register), PF_F32));
|
||||||
@ -270,7 +270,7 @@ implementation
|
|||||||
procedure tarminlinenode.second_sqr_real;
|
procedure tarminlinenode.second_sqr_real;
|
||||||
var
|
var
|
||||||
singleprec: boolean;
|
singleprec: boolean;
|
||||||
op: TAsmOp;
|
pf: TOpPostfix;
|
||||||
begin
|
begin
|
||||||
load_fpu_location(singleprec);
|
load_fpu_location(singleprec);
|
||||||
case current_settings.fputype of
|
case current_settings.fputype of
|
||||||
@ -283,10 +283,10 @@ implementation
|
|||||||
fpu_vfpv3_d16:
|
fpu_vfpv3_d16:
|
||||||
begin
|
begin
|
||||||
if singleprec then
|
if singleprec then
|
||||||
op:=A_FMULS
|
pf:=PF_F32
|
||||||
else
|
else
|
||||||
op:=A_FMULD;
|
pf:=PF_F64;
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,location.register,left.location.register,left.location.register));
|
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg_reg(A_VMUL,location.register,left.location.register,left.location.register),pf));
|
||||||
end;
|
end;
|
||||||
fpu_fpv4_s16:
|
fpu_fpv4_s16:
|
||||||
current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg_reg(A_VMUL,location.register,left.location.register,left.location.register), PF_F32));
|
current_asmdata.CurrAsmList.Concat(setoppostfix(taicpu.op_reg_reg_reg(A_VMUL,location.register,left.location.register,left.location.register), PF_F32));
|
||||||
@ -309,14 +309,7 @@ implementation
|
|||||||
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_SQT,location.register,left.location.register),get_fpu_postfix(resultdef)));
|
current_asmdata.CurrAsmList.concat(setoppostfix(taicpu.op_reg_reg(A_SQT,location.register,left.location.register),get_fpu_postfix(resultdef)));
|
||||||
fpu_vfpv2,
|
fpu_vfpv2,
|
||||||
fpu_vfpv3,
|
fpu_vfpv3,
|
||||||
fpu_vfpv3_d16:
|
fpu_vfpv3_d16,
|
||||||
begin
|
|
||||||
if singleprec then
|
|
||||||
op:=A_FSQRTS
|
|
||||||
else
|
|
||||||
op:=A_FSQRTD;
|
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,location.register,left.location.register));
|
|
||||||
end;
|
|
||||||
fpu_fpv4_s16:
|
fpu_fpv4_s16:
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VSQRT,location.register,left.location.register));
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VSQRT,location.register,left.location.register));
|
||||||
else
|
else
|
||||||
|
@ -432,11 +432,7 @@ implementation
|
|||||||
location:=left.location;
|
location:=left.location;
|
||||||
if (left.location.loc=LOC_CMMREGISTER) then
|
if (left.location.loc=LOC_CMMREGISTER) then
|
||||||
location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
|
location.register:=cg.getmmregister(current_asmdata.CurrAsmList,location.size);
|
||||||
if (location.size=OS_F32) then
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_VNEG,
|
||||||
op:=A_FNEGS
|
|
||||||
else
|
|
||||||
op:=A_FNEGD;
|
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,
|
|
||||||
location.register,left.location.register));
|
location.register,left.location.register));
|
||||||
end;
|
end;
|
||||||
fpu_fpv4_s16:
|
fpu_fpv4_s16:
|
||||||
|
@ -30,7 +30,10 @@ Unit raarmgas;
|
|||||||
cpubase;
|
cpubase;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
tarmsyntax = (asm_legacy, asm_unified);
|
||||||
|
|
||||||
tarmattreader = class(tattreader)
|
tarmattreader = class(tattreader)
|
||||||
|
asmsyntax : tarmsyntax;
|
||||||
actoppostfix : TOpPostfix;
|
actoppostfix : TOpPostfix;
|
||||||
actwideformat : boolean;
|
actwideformat : boolean;
|
||||||
function is_asmopcode(const s: string):boolean;override;
|
function is_asmopcode(const s: string):boolean;override;
|
||||||
@ -66,12 +69,12 @@ Unit raarmgas;
|
|||||||
function tarmattreader.is_register(const s:string):boolean;
|
function tarmattreader.is_register(const s:string):boolean;
|
||||||
type
|
type
|
||||||
treg2str = record
|
treg2str = record
|
||||||
name : string[2];
|
name : string[3];
|
||||||
reg : tregister;
|
reg : tregister;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
extraregs : array[0..19] of treg2str = (
|
extraregs : array[0..19+16] of treg2str = (
|
||||||
(name: 'A1'; reg : NR_R0),
|
(name: 'A1'; reg : NR_R0),
|
||||||
(name: 'A2'; reg : NR_R1),
|
(name: 'A2'; reg : NR_R1),
|
||||||
(name: 'A3'; reg : NR_R2),
|
(name: 'A3'; reg : NR_R2),
|
||||||
@ -91,7 +94,25 @@ Unit raarmgas;
|
|||||||
(name: 'IP'; reg : NR_R12),
|
(name: 'IP'; reg : NR_R12),
|
||||||
(name: 'SP'; reg : NR_R13),
|
(name: 'SP'; reg : NR_R13),
|
||||||
(name: 'LR'; reg : NR_R14),
|
(name: 'LR'; reg : NR_R14),
|
||||||
(name: 'PC'; reg : NR_R15));
|
(name: 'PC'; reg : NR_R15),
|
||||||
|
|
||||||
|
(name: 'C0'; reg : NR_CR0),
|
||||||
|
(name: 'C1'; reg : NR_CR1),
|
||||||
|
(name: 'C2'; reg : NR_CR2),
|
||||||
|
(name: 'C3'; reg : NR_CR3),
|
||||||
|
(name: 'C4'; reg : NR_CR4),
|
||||||
|
(name: 'C5'; reg : NR_CR5),
|
||||||
|
(name: 'C6'; reg : NR_CR6),
|
||||||
|
(name: 'C7'; reg : NR_CR7),
|
||||||
|
(name: 'C8'; reg : NR_CR8),
|
||||||
|
(name: 'C9'; reg : NR_CR9),
|
||||||
|
(name: 'C10'; reg : NR_CR10),
|
||||||
|
(name: 'C11'; reg : NR_CR11),
|
||||||
|
(name: 'C12'; reg : NR_CR12),
|
||||||
|
(name: 'C13'; reg : NR_CR13),
|
||||||
|
(name: 'C14'; reg : NR_CR14),
|
||||||
|
(name: 'C15'; reg : NR_CR15)
|
||||||
|
);
|
||||||
|
|
||||||
var
|
var
|
||||||
i : longint;
|
i : longint;
|
||||||
@ -101,7 +122,7 @@ Unit raarmgas;
|
|||||||
{ reg found?
|
{ reg found?
|
||||||
possible aliases are always 2 char
|
possible aliases are always 2 char
|
||||||
}
|
}
|
||||||
if result or (length(s)<>2) then
|
if result or (not (length(s) in [2,3])) then
|
||||||
exit;
|
exit;
|
||||||
for i:=low(extraregs) to high(extraregs) do
|
for i:=low(extraregs) to high(extraregs) do
|
||||||
begin
|
begin
|
||||||
@ -241,7 +262,9 @@ Unit raarmgas;
|
|||||||
do_error;
|
do_error;
|
||||||
oper.opr.ref.shiftimm := shift;
|
oper.opr.ref.shiftimm := shift;
|
||||||
test_end(require_rbracket);
|
test_end(require_rbracket);
|
||||||
end;
|
end
|
||||||
|
else
|
||||||
|
test_end(require_rbracket);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -785,6 +808,18 @@ Unit raarmgas;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function getregsetindex(reg: tregister): integer;
|
||||||
|
begin
|
||||||
|
if getsubreg(reg)=R_SUBFS then
|
||||||
|
begin
|
||||||
|
result:=getsupreg(reg)*2;
|
||||||
|
if result>32 then
|
||||||
|
result:=result-63;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result:=getsupreg(reg);
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
tempreg : tregister;
|
tempreg : tregister;
|
||||||
ireg : tsuperregister;
|
ireg : tsuperregister;
|
||||||
@ -958,7 +993,7 @@ Unit raarmgas;
|
|||||||
oper.opr.typ:=OPR_REGISTER;
|
oper.opr.typ:=OPR_REGISTER;
|
||||||
oper.opr.reg:=tempreg;
|
oper.opr.reg:=tempreg;
|
||||||
end
|
end
|
||||||
else if (actasmtoken=AS_NOT) and (actopcode in [A_LDM,A_STM,A_FLDM,A_FSTM]) then
|
else if (actasmtoken=AS_NOT) and (actopcode in [A_LDM,A_STM,A_FLDM,A_FSTM,A_VLDM,A_VSTM]) then
|
||||||
begin
|
begin
|
||||||
consume(AS_NOT);
|
consume(AS_NOT);
|
||||||
oper.opr.typ:=OPR_REFERENCE;
|
oper.opr.typ:=OPR_REFERENCE;
|
||||||
@ -976,11 +1011,11 @@ Unit raarmgas;
|
|||||||
registerset:=[];
|
registerset:=[];
|
||||||
regtype:=R_INVALIDREGISTER;
|
regtype:=R_INVALIDREGISTER;
|
||||||
subreg:=R_SUBNONE;
|
subreg:=R_SUBNONE;
|
||||||
while true do
|
while actasmtoken<>AS_RSBRACKET do
|
||||||
begin
|
begin
|
||||||
if actasmtoken=AS_REGISTER then
|
if actasmtoken=AS_REGISTER then
|
||||||
begin
|
begin
|
||||||
include(registerset,getsupreg(actasmregister));
|
include(registerset,getregsetindex(actasmregister));
|
||||||
if regtype<>R_INVALIDREGISTER then
|
if regtype<>R_INVALIDREGISTER then
|
||||||
begin
|
begin
|
||||||
if (getregtype(actasmregister)<>regtype) or
|
if (getregtype(actasmregister)<>regtype) or
|
||||||
@ -997,7 +1032,7 @@ Unit raarmgas;
|
|||||||
if actasmtoken=AS_MINUS then
|
if actasmtoken=AS_MINUS then
|
||||||
begin
|
begin
|
||||||
consume(AS_MINUS);
|
consume(AS_MINUS);
|
||||||
for ireg:=getsupreg(tempreg) to getsupreg(actasmregister) do
|
for ireg:=getregsetindex(tempreg) to getregsetindex(actasmregister) do
|
||||||
include(registerset,ireg);
|
include(registerset,ireg);
|
||||||
consume(AS_REGISTER);
|
consume(AS_REGISTER);
|
||||||
end;
|
end;
|
||||||
@ -1137,8 +1172,16 @@ Unit raarmgas;
|
|||||||
case actasmtoken of
|
case actasmtoken of
|
||||||
AS_COMMA: { Operand delimiter }
|
AS_COMMA: { Operand delimiter }
|
||||||
Begin
|
Begin
|
||||||
if ((instr.opcode in [A_MOV, A_MVN, A_CMP, A_CMN, A_TST, A_TEQ]) and (operandnum=2)) or
|
if ((instr.opcode in [A_MOV,A_MVN,A_CMP,A_CMN,A_TST,A_TEQ,
|
||||||
((operandnum=3) and not(instr.opcode in [A_UMLAL,A_UMULL,A_SMLAL,A_SMULL,A_MLA,A_MRC,A_MCR,A_MCRR,A_MRRC])) then
|
A_UXTB,A_UXTH,A_UXTB16,
|
||||||
|
A_SXTB,A_SXTH,A_SXTB16]) and
|
||||||
|
(operandnum=2)) or
|
||||||
|
((operandnum=3) and not(instr.opcode in [A_UMLAL,A_UMULL,A_SMLAL,A_SMULL,A_MLA,A_UMAAL,A_MLS,
|
||||||
|
A_SMLABB,A_SMLABT,A_SMLATB,A_SMLATT,A_SMMLA,A_SMMLS,A_SMLAD,A_SMLALD,A_SMLSD,
|
||||||
|
A_SMLALBB,A_SMLALBT,A_SMLALTB,A_SMLALTT,A_SMLSLD,
|
||||||
|
A_MRC,A_MCR,A_MCRR,A_MRRC,A_STREXD,A_STRD,
|
||||||
|
A_VMOV,
|
||||||
|
A_SBFX,A_UBFX,A_BFI])) then
|
||||||
begin
|
begin
|
||||||
Consume(AS_COMMA);
|
Consume(AS_COMMA);
|
||||||
if not(TryBuildShifterOp(instr.Operands[operandnum+1] as tarmoperand)) then
|
if not(TryBuildShifterOp(instr.Operands[operandnum+1] as tarmoperand)) then
|
||||||
@ -1174,25 +1217,34 @@ Unit raarmgas;
|
|||||||
|
|
||||||
const
|
const
|
||||||
{ sorted by length so longer postfixes will match first }
|
{ sorted by length so longer postfixes will match first }
|
||||||
postfix2strsorted : array[1..31] of string[3] = (
|
postfix2strsorted : array[1..70] of string[9] = (
|
||||||
'IAD','DBD','FDD','EAD',
|
'.F32.S32','.F32.U32','.S32.F32','.U32.F32','.F64.S32','.F64.U32','.S32.F64','.U32.F64',
|
||||||
'IAS','DBS','FDS','EAS',
|
'.F32.S16','.F32.U16','.S16.F32','.U16.F32','.F64.S16','.F64.U16','.S16.F64','.U16.F64',
|
||||||
'IAX','DBX','FDX','EAX',
|
'.F32.F64','.F64.F32',
|
||||||
'EP','SB','BT','SH',
|
'.I16','.I32','.I64','.S16','.S32','.S64','.U16','.U32','.U64','.F32','.F64',
|
||||||
'IA','IB','DA','DB','FD','FA','ED','EA',
|
'IAD','DBD','FDD','EAD','IAS','DBS','FDS','EAS','IAX','DBX','FDX','EAX',
|
||||||
'B','D','E','P','T','H','S');
|
'.16','.32','.64','.I8','.S8','.U8','.P8',
|
||||||
|
'EP','SB','BT','SH','IA','IB','DA','DB','FD','FA','ED','EA',
|
||||||
|
'.8','S','D','E','P','X','R','B','H','T');
|
||||||
|
|
||||||
postfixsorted : array[1..31] of TOpPostfix = (
|
postfixsorted : array[1..70] of TOpPostfix = (
|
||||||
PF_IAD,PF_DBD,PF_FDD,PF_EAD,
|
PF_F32S32,PF_F32U32,PF_S32F32,PF_U32F32,PF_F64S32,PF_F64U32,PF_S32F64,PF_U32F64,
|
||||||
PF_IAS,PF_DBS,PF_FDS,PF_EAS,
|
PF_F32S16,PF_F32U16,PF_S16F32,PF_U16F32,PF_F64S16,PF_F64U16,PF_S16F64,PF_U16F64,
|
||||||
PF_IAX,PF_DBX,PF_FDX,PF_EAX,
|
PF_F32F64,PF_F64F32,
|
||||||
PF_EP,PF_SB,PF_BT,PF_SH,
|
PF_I16,PF_I32,
|
||||||
PF_IA,PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,PF_ED,PF_EA,
|
PF_I64,PF_S16,PF_S32,PF_S64,PF_U16,PF_U32,PF_U64,PF_F32,
|
||||||
PF_B,PF_D,PF_E,PF_P,PF_T,PF_H,PF_S);
|
PF_F64,PF_IAD,PF_DBD,PF_FDD,PF_EAD,
|
||||||
|
PF_IAS,PF_DBS,PF_FDS,PF_EAS,PF_IAX,
|
||||||
|
PF_DBX,PF_FDX,PF_EAX,PF_16,PF_32,
|
||||||
|
PF_64,PF_I8,PF_S8,PF_U8,PF_P8,
|
||||||
|
PF_EP,PF_SB,PF_BT,PF_SH,PF_IA,
|
||||||
|
PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,
|
||||||
|
PF_ED,PF_EA,PF_8,PF_S,PF_D,PF_E,
|
||||||
|
PF_P,PF_X,PF_R,PF_B,PF_H,PF_T);
|
||||||
|
|
||||||
var
|
var
|
||||||
j : longint;
|
j, j2 : longint;
|
||||||
hs : string;
|
hs,hs2 : string;
|
||||||
maxlen : longint;
|
maxlen : longint;
|
||||||
icond : tasmcond;
|
icond : tasmcond;
|
||||||
Begin
|
Begin
|
||||||
@ -1222,59 +1274,106 @@ Unit raarmgas;
|
|||||||
end;
|
end;
|
||||||
maxlen:=max(length(hs),5);
|
maxlen:=max(length(hs),5);
|
||||||
actopcode:=A_NONE;
|
actopcode:=A_NONE;
|
||||||
for j:=maxlen downto 1 do
|
j2:=maxlen;
|
||||||
|
hs2:=hs;
|
||||||
|
while j2>1 do
|
||||||
begin
|
begin
|
||||||
actopcode:=tasmop(PtrUInt(iasmops.Find(copy(hs,1,j))));
|
hs:=hs2;
|
||||||
if actopcode<>A_NONE then
|
while j2>=1 do
|
||||||
begin
|
begin
|
||||||
actasmtoken:=AS_OPCODE;
|
actopcode:=tasmop(PtrUInt(iasmops.Find(copy(hs,1,j2))));
|
||||||
{ strip op code }
|
if actopcode<>A_NONE then
|
||||||
delete(hs,1,j);
|
begin
|
||||||
break;
|
actasmtoken:=AS_OPCODE;
|
||||||
|
{ strip op code }
|
||||||
|
delete(hs,1,j2);
|
||||||
|
dec(j2);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
dec(j2);
|
||||||
end;
|
end;
|
||||||
end;
|
if actopcode=A_NONE then
|
||||||
if actopcode=A_NONE then
|
exit;
|
||||||
exit;
|
|
||||||
|
|
||||||
{ search for condition, conditions are always 2 chars }
|
if asmsyntax=asm_unified then
|
||||||
if length(hs)>1 then
|
|
||||||
begin
|
|
||||||
for icond:=low(tasmcond) to high(tasmcond) do
|
|
||||||
begin
|
begin
|
||||||
if copy(hs,1,2)=uppercond2str[icond] then
|
{ check for postfix }
|
||||||
|
if (length(hs)>0) and (actoppostfix=PF_None) then
|
||||||
begin
|
begin
|
||||||
actcondition:=icond;
|
for j:=low(postfixsorted) to high(postfixsorted) do
|
||||||
{ strip condition }
|
begin
|
||||||
|
if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then
|
||||||
|
begin
|
||||||
|
if not ((length(hs)-length(postfix2strsorted[j])) in [0,2,4]) then
|
||||||
|
continue;
|
||||||
|
|
||||||
|
actoppostfix:=postfixsorted[j];
|
||||||
|
{ strip postfix }
|
||||||
|
delete(hs,1,length(postfix2strsorted[j]));
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ search for condition, conditions are always 2 chars }
|
||||||
|
if length(hs)>1 then
|
||||||
|
begin
|
||||||
|
for icond:=low(tasmcond) to high(tasmcond) do
|
||||||
|
begin
|
||||||
|
if copy(hs,1,2)=uppercond2str[icond] then
|
||||||
|
begin
|
||||||
|
actcondition:=icond;
|
||||||
|
{ strip condition }
|
||||||
|
delete(hs,1,2);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ search for condition, conditions are always 2 chars }
|
||||||
|
if length(hs)>1 then
|
||||||
|
begin
|
||||||
|
for icond:=low(tasmcond) to high(tasmcond) do
|
||||||
|
begin
|
||||||
|
if copy(hs,1,2)=uppercond2str[icond] then
|
||||||
|
begin
|
||||||
|
actcondition:=icond;
|
||||||
|
{ strip condition }
|
||||||
|
delete(hs,1,2);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ check for postfix }
|
||||||
|
if (length(hs)>0) and (actoppostfix=PF_None) then
|
||||||
|
begin
|
||||||
|
for j:=low(postfixsorted) to high(postfixsorted) do
|
||||||
|
begin
|
||||||
|
if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then
|
||||||
|
begin
|
||||||
|
actoppostfix:=postfixsorted[j];
|
||||||
|
{ strip postfix }
|
||||||
|
delete(hs,1,length(postfix2strsorted[j]));
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ check for format postfix }
|
||||||
|
if length(hs)>0 then
|
||||||
|
begin
|
||||||
|
if copy(hs,1,2) = '.W' then
|
||||||
|
begin
|
||||||
|
actwideformat:=true;
|
||||||
delete(hs,1,2);
|
delete(hs,1,2);
|
||||||
break;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
{ if we stripped all postfixes, it's a valid opcode }
|
||||||
|
is_asmopcode:=length(hs)=0;
|
||||||
|
if is_asmopcode = true then
|
||||||
|
break;
|
||||||
end;
|
end;
|
||||||
{ check for postfix }
|
|
||||||
if length(hs)>0 then
|
|
||||||
begin
|
|
||||||
for j:=low(postfixsorted) to high(postfixsorted) do
|
|
||||||
begin
|
|
||||||
if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then
|
|
||||||
begin
|
|
||||||
actoppostfix:=postfixsorted[j];
|
|
||||||
{ strip postfix }
|
|
||||||
delete(hs,1,length(postfix2strsorted[j]));
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
{ check for format postfix }
|
|
||||||
if length(hs)>0 then
|
|
||||||
begin
|
|
||||||
if upcase(copy(hs,1,2)) = '.W' then
|
|
||||||
begin
|
|
||||||
actwideformat:=true;
|
|
||||||
delete(hs,1,2);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
{ if we stripped all postfixes, it's a valid opcode }
|
|
||||||
is_asmopcode:=length(hs)=0;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1337,6 +1436,8 @@ Unit raarmgas;
|
|||||||
instr.Free;
|
instr.Free;
|
||||||
actoppostfix:=PF_None;
|
actoppostfix:=PF_None;
|
||||||
actwideformat:=false;
|
actwideformat:=false;
|
||||||
|
|
||||||
|
asmsyntax:=asm_legacy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@ interface
|
|||||||
{$endif i386}
|
{$endif i386}
|
||||||
{$ifdef arm}
|
{$ifdef arm}
|
||||||
RELOC_RELATIVE_24,
|
RELOC_RELATIVE_24,
|
||||||
|
RELOC_RELATIVE_24_THUMB,
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
{ Relative relocation }
|
{ Relative relocation }
|
||||||
RELOC_RELATIVE,
|
RELOC_RELATIVE,
|
||||||
|
@ -261,9 +261,9 @@ interface
|
|||||||
TLSDIR_SIZE = $18;
|
TLSDIR_SIZE = $18;
|
||||||
{$endif i386}
|
{$endif i386}
|
||||||
{$ifdef arm}
|
{$ifdef arm}
|
||||||
COFF_MAGIC = $1c0;
|
|
||||||
COFF_OPT_MAGIC = $10b;
|
COFF_OPT_MAGIC = $10b;
|
||||||
TLSDIR_SIZE = $18;
|
TLSDIR_SIZE = $18;
|
||||||
|
function COFF_MAGIC: word;
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
{$ifdef x86_64}
|
{$ifdef x86_64}
|
||||||
COFF_MAGIC = $8664;
|
COFF_MAGIC = $8664;
|
||||||
@ -422,6 +422,11 @@ implementation
|
|||||||
IMAGE_REL_ARM_BLX11 = $0009;
|
IMAGE_REL_ARM_BLX11 = $0009;
|
||||||
IMAGE_REL_ARM_SECTION = $000E; { Section table index }
|
IMAGE_REL_ARM_SECTION = $000E; { Section table index }
|
||||||
IMAGE_REL_ARM_SECREL = $000F; { Offset within section }
|
IMAGE_REL_ARM_SECREL = $000F; { Offset within section }
|
||||||
|
IMAGE_REL_ARM_MOV32A = $0010; { 32-bit VA applied to MOVW+MOVT pair, added to existing imm (ARM) }
|
||||||
|
IMAGE_REL_ARM_MOV32T = $0011; { 32-bit VA applied to MOVW+MOVT pair, added to existing imm (THUMB) }
|
||||||
|
IMAGE_REL_ARM_BRANCH20T = $0012; { Thumb: 20 most significant bits of 32 bit B cond instruction }
|
||||||
|
IMAGE_REL_ARM_BRANCH24T = $0014; { Thumb: 24 most significant bits of 32 bit B uncond instruction }
|
||||||
|
IMAGE_REL_ARM_BLX23T = $0015; { 23 most significant bits of 32 bit BL/BLX instruction. Transformed to BLX if target is Thumb }
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
|
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
@ -913,6 +918,14 @@ const pemagic : array[0..3] of byte = (
|
|||||||
if (relocval<>$3f) and (relocval<>0) then
|
if (relocval<>$3f) and (relocval<>0) then
|
||||||
internalerror(200606085); { offset overflow }
|
internalerror(200606085); { offset overflow }
|
||||||
end;
|
end;
|
||||||
|
RELOC_RELATIVE_24_THUMB:
|
||||||
|
begin
|
||||||
|
relocval:=longint(relocval - objsec.mempos - objreloc.dataoffset) shr 1 - 4;
|
||||||
|
address:=address or ((relocval shr 1) and $ffffff) or ((relocval and 1) shl 24);
|
||||||
|
relocval:=relocval shr 25;
|
||||||
|
if (relocval<>$3f) and (relocval<>0) then
|
||||||
|
internalerror(200606085); { offset overflow }
|
||||||
|
end;
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
{$ifdef x86_64}
|
{$ifdef x86_64}
|
||||||
{ 64 bit coff only }
|
{ 64 bit coff only }
|
||||||
@ -1009,10 +1022,9 @@ const pemagic : array[0..3] of byte = (
|
|||||||
result:=aname
|
result:=aname
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
{ non-PECOFF targets lack rodata support.
|
{ non-PECOFF targets lack rodata support }
|
||||||
TODO: WinCE likely supports it, but needs testing. }
|
|
||||||
if (atype in [sec_rodata,sec_rodata_norel]) and
|
if (atype in [sec_rodata,sec_rodata_norel]) and
|
||||||
not (target_info.system in systems_windows) then
|
not (target_info.system in systems_all_windows) then
|
||||||
atype:=sec_data;
|
atype:=sec_data;
|
||||||
secname:=coffsecnames[atype];
|
secname:=coffsecnames[atype];
|
||||||
if create_smartlink_sections and
|
if create_smartlink_sections and
|
||||||
@ -1038,8 +1050,7 @@ const pemagic : array[0..3] of byte = (
|
|||||||
begin
|
begin
|
||||||
if (aType in [sec_rodata,sec_rodata_norel]) then
|
if (aType in [sec_rodata,sec_rodata_norel]) then
|
||||||
begin
|
begin
|
||||||
{ TODO: WinCE needs testing }
|
if (target_info.system in systems_all_windows) then
|
||||||
if (target_info.system in systems_windows) then
|
|
||||||
aType:=sec_rodata_norel
|
aType:=sec_rodata_norel
|
||||||
else
|
else
|
||||||
aType:=sec_data;
|
aType:=sec_data;
|
||||||
@ -1279,6 +1290,10 @@ const pemagic : array[0..3] of byte = (
|
|||||||
rel.reloctype:=IMAGE_REL_ARM_ADDR32NB;
|
rel.reloctype:=IMAGE_REL_ARM_ADDR32NB;
|
||||||
RELOC_SECREL32 :
|
RELOC_SECREL32 :
|
||||||
rel.reloctype:=IMAGE_REL_ARM_SECREL;
|
rel.reloctype:=IMAGE_REL_ARM_SECREL;
|
||||||
|
RELOC_RELATIVE_24 :
|
||||||
|
rel.reloctype:=IMAGE_REL_ARM_BRANCH24;
|
||||||
|
RELOC_RELATIVE_24_THUMB:
|
||||||
|
rel.reloctype:=IMAGE_REL_ARM_BLX24;
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
RELOC_RELATIVE :
|
RELOC_RELATIVE :
|
||||||
@ -1597,6 +1612,8 @@ const pemagic : array[0..3] of byte = (
|
|||||||
rel_type:=RELOC_RELATIVE_24;
|
rel_type:=RELOC_RELATIVE_24;
|
||||||
IMAGE_REL_ARM_SECREL:
|
IMAGE_REL_ARM_SECREL:
|
||||||
rel_type:=RELOC_SECREL32;
|
rel_type:=RELOC_SECREL32;
|
||||||
|
IMAGE_REL_ARM_BLX24:
|
||||||
|
rel_type:=RELOC_RELATIVE_24_THUMB;
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
IMAGE_REL_I386_PCRLONG :
|
IMAGE_REL_I386_PCRLONG :
|
||||||
@ -2962,6 +2979,15 @@ const pemagic : array[0..3] of byte = (
|
|||||||
DLLReader.Free;
|
DLLReader.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$ifdef arm}
|
||||||
|
function COFF_MAGIC: word;
|
||||||
|
begin
|
||||||
|
if GenerateThumb2Code and (current_settings.cputype>=cpu_armv7) then
|
||||||
|
COFF_MAGIC:=$1c4 // IMAGE_FILE_MACHINE_ARMNT
|
||||||
|
else
|
||||||
|
COFF_MAGIC:=$1c0; // IMAGE_FILE_MACHINE_ARM
|
||||||
|
end;
|
||||||
|
{$endif arm}
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
Initialize
|
Initialize
|
||||||
@ -3045,7 +3071,7 @@ const pemagic : array[0..3] of byte = (
|
|||||||
asmbin : '';
|
asmbin : '';
|
||||||
asmcmd : '';
|
asmcmd : '';
|
||||||
supported_targets : [system_arm_wince];
|
supported_targets : [system_arm_wince];
|
||||||
flags : [af_outputbinary];
|
flags : [af_outputbinary,af_smartlink_sections];
|
||||||
labelprefix : '.L';
|
labelprefix : '.L';
|
||||||
comment : '';
|
comment : '';
|
||||||
dollarsign: '$';
|
dollarsign: '$';
|
||||||
|
@ -290,12 +290,24 @@ unit raatt;
|
|||||||
end;
|
end;
|
||||||
{$endif POWERPC}
|
{$endif POWERPC}
|
||||||
{$if defined(ARM)}
|
{$if defined(ARM)}
|
||||||
{ Thumb-2 instructions can have a .W postfix to indicate 32bit instructions
|
{
|
||||||
|
Thumb-2 instructions can have a .W postfix to indicate 32bit instructions,
|
||||||
|
Also in unified syntax sizes and types are indicated with something like a .<dt> prefix for example
|
||||||
}
|
}
|
||||||
case c of
|
case c of
|
||||||
'.':
|
'.':
|
||||||
begin
|
begin
|
||||||
actasmpattern:=actasmpattern+c;
|
if len>1 then
|
||||||
|
begin
|
||||||
|
while c in ['A'..'Z','a'..'z','0'..'9','_','.'] do
|
||||||
|
begin
|
||||||
|
inc(len);
|
||||||
|
actasmpattern[len]:=c;
|
||||||
|
c:=current_scanner.asmgetchar;
|
||||||
|
end;
|
||||||
|
actasmpattern[0]:=chr(len);
|
||||||
|
end;
|
||||||
|
{actasmpattern:=actasmpattern+c;
|
||||||
c:=current_scanner.asmgetchar;
|
c:=current_scanner.asmgetchar;
|
||||||
|
|
||||||
if upcase(c) = 'W' then
|
if upcase(c) = 'W' then
|
||||||
@ -304,7 +316,7 @@ unit raatt;
|
|||||||
c:=current_scanner.asmgetchar;
|
c:=current_scanner.asmgetchar;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
internalerror(2010122301);
|
internalerror(2010122301);}
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
{$endif ARM}
|
{$endif ARM}
|
||||||
|
@ -211,6 +211,7 @@
|
|||||||
,as_i8086_nasm
|
,as_i8086_nasm
|
||||||
,as_i8086_nasmobj
|
,as_i8086_nasmobj
|
||||||
,as_gas_powerpc_xcoff
|
,as_gas_powerpc_xcoff
|
||||||
|
,as_arm_elf32
|
||||||
);
|
);
|
||||||
|
|
||||||
tlink = (ld_none,
|
tlink = (ld_none,
|
||||||
|
@ -582,7 +582,7 @@ unit i_linux;
|
|||||||
Cprefix : '';
|
Cprefix : '';
|
||||||
newline : #10;
|
newline : #10;
|
||||||
dirsep : '/';
|
dirsep : '/';
|
||||||
assem : as_gas;
|
assem : as_arm_elf32;
|
||||||
assemextern : as_gas;
|
assemextern : as_gas;
|
||||||
link : ld_none;
|
link : ld_none;
|
||||||
linkextern : ld_linux;
|
linkextern : ld_linux;
|
||||||
@ -648,7 +648,7 @@ unit i_linux;
|
|||||||
Cprefix : '';
|
Cprefix : '';
|
||||||
newline : #10;
|
newline : #10;
|
||||||
dirsep : '/';
|
dirsep : '/';
|
||||||
assem : as_gas;
|
assem : as_arm_elf32;
|
||||||
assemextern : as_gas;
|
assemextern : as_gas;
|
||||||
link : ld_none;
|
link : ld_none;
|
||||||
linkextern : ld_linux;
|
linkextern : ld_linux;
|
||||||
@ -714,7 +714,7 @@ unit i_linux;
|
|||||||
Cprefix : '';
|
Cprefix : '';
|
||||||
newline : #10;
|
newline : #10;
|
||||||
dirsep : '/';
|
dirsep : '/';
|
||||||
assem : as_gas;
|
assem : as_arm_elf32;
|
||||||
assemextern : as_gas;
|
assemextern : as_gas;
|
||||||
link : ld_none;
|
link : ld_none;
|
||||||
linkextern : ld_linux;
|
linkextern : ld_linux;
|
||||||
@ -778,7 +778,7 @@ unit i_linux;
|
|||||||
Cprefix : '';
|
Cprefix : '';
|
||||||
newline : #10;
|
newline : #10;
|
||||||
dirsep : '/';
|
dirsep : '/';
|
||||||
assem : as_gas;
|
assem : as_arm_elf32;
|
||||||
assemextern : as_gas;
|
assemextern : as_gas;
|
||||||
link : ld_none;
|
link : ld_none;
|
||||||
linkextern : ld_linux;
|
linkextern : ld_linux;
|
||||||
|
@ -198,7 +198,7 @@ unit i_win;
|
|||||||
Cprefix : '';
|
Cprefix : '';
|
||||||
newline : #13#10;
|
newline : #13#10;
|
||||||
dirsep : '\';
|
dirsep : '\';
|
||||||
assem : as_gas;
|
assem : as_arm_pecoffwince;
|
||||||
assemextern : as_gas;
|
assemextern : as_gas;
|
||||||
link : ld_int_windows;
|
link : ld_int_windows;
|
||||||
linkextern : ld_windows;
|
linkextern : ld_windows;
|
||||||
|
@ -46,7 +46,7 @@ Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
|
|||||||
begin
|
begin
|
||||||
{ Enable FPU exceptions, but disable INEXACT, UNDERFLOW, DENORMAL }
|
{ Enable FPU exceptions, but disable INEXACT, UNDERFLOW, DENORMAL }
|
||||||
asm
|
asm
|
||||||
fmrx r0,fpscr
|
vmrs r0,fpscr
|
||||||
// set "round to nearest" mode
|
// set "round to nearest" mode
|
||||||
and r0,r0,#0xff3fffff
|
and r0,r0,#0xff3fffff
|
||||||
// mask "exception happened" and overflow flags
|
// mask "exception happened" and overflow flags
|
||||||
@ -61,7 +61,7 @@ begin
|
|||||||
// enable invalid operation, div-by-zero and overflow exceptions
|
// enable invalid operation, div-by-zero and overflow exceptions
|
||||||
orr r0,r0,#0x00000700
|
orr r0,r0,#0x00000700
|
||||||
{$endif}
|
{$endif}
|
||||||
fmxr fpscr,r0
|
vmsr fpscr,r0
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
@ -161,13 +161,13 @@ const
|
|||||||
|
|
||||||
function VFP_GetCW : dword; nostackframe; assembler;
|
function VFP_GetCW : dword; nostackframe; assembler;
|
||||||
asm
|
asm
|
||||||
fmrx r0,fpscr
|
vmrs r0,fpscr
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure VFP_SetCW(cw : dword); nostackframe; assembler;
|
procedure VFP_SetCW(cw : dword); nostackframe; assembler;
|
||||||
asm
|
asm
|
||||||
fmxr fpscr,r0
|
vmsr fpscr,r0
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,12 +18,12 @@ function fpc_setjmp(var S : jmp_buf) : longint;assembler;[Public, alias : 'FPC_S
|
|||||||
asm
|
asm
|
||||||
{$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
|
{$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
|
||||||
{$if defined(CPUARMV3) or defined(CPUARMV4) or defined(CPUARMV5)}
|
{$if defined(CPUARMV3) or defined(CPUARMV4) or defined(CPUARMV5)}
|
||||||
fstmiax r0!, {d8-d15}
|
vstmia r0!, {d8-d15}
|
||||||
// according to the ARM Developer Suite Assembler Guide Version 1.2
|
// according to the ARM Developer Suite Assembler Guide Version 1.2
|
||||||
// fstmiad increases the address register always by 2n+1 words, so fix this
|
// fstmiad increases the address register always by 2n+1 words, so fix this
|
||||||
sub r0,r0,#4
|
sub r0,r0,#4
|
||||||
{$else}
|
{$else}
|
||||||
fstmiad r0!, {d8-d15}
|
vstmia r0!, {d8-d15}
|
||||||
{$endif}
|
{$endif}
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ procedure fpc_longjmp(var S : jmp_buf;value : longint);assembler;[Public, alias
|
|||||||
it eq
|
it eq
|
||||||
moveq r0, #1
|
moveq r0, #1
|
||||||
{$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
|
{$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
|
||||||
fldmiad ip!, {d8-d15}
|
vldmia ip!, {d8-d15}
|
||||||
{$endif}
|
{$endif}
|
||||||
ldmia ip!, {v1-v6, sl, fp}
|
ldmia ip!, {v1-v6, sl, fp}
|
||||||
ldr sp, [ip]
|
ldr sp, [ip]
|
||||||
@ -103,12 +103,12 @@ procedure fpc_longjmp(var S : jmp_buf;value : longint);assembler;[Public, alias
|
|||||||
moveq r0, #1
|
moveq r0, #1
|
||||||
{$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
|
{$if defined(FPUVFPV2) or defined(FPUVFPV3) or defined(FPUVFPV3_D16)}
|
||||||
{$if defined(CPUARMV3) or defined(CPUARMV4) or defined(CPUARMV5)}
|
{$if defined(CPUARMV3) or defined(CPUARMV4) or defined(CPUARMV5)}
|
||||||
fldmiax ip!, {d8-d15}
|
vldmia ip!, {d8-d15}
|
||||||
// according to the ARM Developer Suite Assembler Guide Version 1.2
|
// according to the ARM Developer Suite Assembler Guide Version 1.2
|
||||||
// increases fldmiax the address register always by 2n+1 words, so fix this
|
// increases fldmiax the address register always by 2n+1 words, so fix this
|
||||||
sub ip,ip,#4
|
sub ip,ip,#4
|
||||||
{$else}
|
{$else}
|
||||||
fldmiad ip!, {d8-d15}
|
vldmia ip!, {d8-d15}
|
||||||
{$endif}
|
{$endif}
|
||||||
{$endif}
|
{$endif}
|
||||||
ldmia ip,{v1-v6, sl, fp, sp, pc}
|
ldmia ip,{v1-v6, sl, fp, sp, pc}
|
||||||
|
Loading…
Reference in New Issue
Block a user