mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-02 18:58:24 +02:00
Add missing NOP, and B instruction forms.
Move ThumbFunc flag from section to symbol. Make .w forms optional the other way around. If .w is explicitly put on an instruction the assembler should always chose a wide form. git-svn-id: branches/laksen/armiw@29341 -
This commit is contained in:
parent
de00a1d76d
commit
71cdedea82
@ -93,6 +93,7 @@ uses
|
||||
OT_REG64 = $00201008;
|
||||
OT_VREG = $00201010; { vector register }
|
||||
OT_REGF = $00201020; { coproc register }
|
||||
OT_REGS = $00201040; { special register with mask }
|
||||
OT_MEMORY = $00204000; { register number in 'basereg' }
|
||||
OT_MEM8 = $00204001;
|
||||
OT_MEM16 = $00204002;
|
||||
@ -1453,10 +1454,6 @@ implementation
|
||||
|
||||
|
||||
procedure gather_it_info(list: TAsmList);
|
||||
const
|
||||
opCount: array[A_IT..A_ITTTT] of longint =
|
||||
(1,2,2,3,3,3,3,
|
||||
4,4,4,4,4,4,4,4);
|
||||
var
|
||||
curtai: tai;
|
||||
in_it: boolean;
|
||||
@ -1479,7 +1476,7 @@ implementation
|
||||
else
|
||||
begin
|
||||
in_it:=true;
|
||||
it_count:=opCount[taicpu(curtai).opcode];
|
||||
it_count:=GetITLevels(taicpu(curtai).opcode);
|
||||
end;
|
||||
end;
|
||||
else
|
||||
@ -1502,8 +1499,51 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ Expands pseudo instructions ( mov r1,r2,lsl #4 -> lsl r1,r2,#4) }
|
||||
procedure expand_instructions(list: TAsmList);
|
||||
var
|
||||
curtai: tai;
|
||||
begin
|
||||
curtai:=tai(list.First);
|
||||
while assigned(curtai) do
|
||||
begin
|
||||
case curtai.typ of
|
||||
ait_instruction:
|
||||
begin
|
||||
case taicpu(curtai).opcode of
|
||||
A_MOV:
|
||||
begin
|
||||
if (taicpu(curtai).ops=3) and
|
||||
(taicpu(curtai).oper[2]^.typ=top_shifterop) then
|
||||
begin
|
||||
case taicpu(curtai).oper[2]^.shifterop^.shiftmode of
|
||||
SM_LSL: taicpu(curtai).opcode:=A_LSL;
|
||||
SM_LSR: taicpu(curtai).opcode:=A_LSR;
|
||||
SM_ASR: taicpu(curtai).opcode:=A_ASR;
|
||||
SM_ROR: taicpu(curtai).opcode:=A_ROR;
|
||||
SM_RRX: taicpu(curtai).opcode:=A_RRX;
|
||||
end;
|
||||
|
||||
if taicpu(curtai).oper[2]^.shifterop^.rs=NR_NO then
|
||||
taicpu(curtai).loadconst(2, taicpu(curtai).oper[2]^.shifterop^.shiftimm)
|
||||
else
|
||||
taicpu(curtai).loadreg(2, taicpu(curtai).oper[2]^.shifterop^.rs);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
curtai:=tai(curtai.Next);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure finalizearmcode(list, listtoinsert: TAsmList);
|
||||
begin
|
||||
expand_instructions(list);
|
||||
|
||||
{ Do Thumb-2 16bit -> 32bit transformations }
|
||||
if GenerateThumb2Code then
|
||||
begin
|
||||
@ -1712,6 +1752,9 @@ implementation
|
||||
else
|
||||
if (ot and OT_FPUREG)=OT_FPUREG then
|
||||
s:=s+'fpureg'
|
||||
else
|
||||
if (ot and OT_REGS)=OT_REGS then
|
||||
s:=s+'sreg'
|
||||
else
|
||||
if (ot and OT_REGF)=OT_REGF then
|
||||
s:=s+'creg'
|
||||
@ -2109,6 +2152,10 @@ implementation
|
||||
begin
|
||||
ot:=OT_CONDITION;
|
||||
end;
|
||||
top_specialreg:
|
||||
begin
|
||||
ot:=OT_REGS;
|
||||
end;
|
||||
else
|
||||
begin writeln(typ);
|
||||
internalerror(200402261); end;
|
||||
@ -2166,10 +2213,10 @@ implementation
|
||||
end;
|
||||
|
||||
{ Check wideformat flag }
|
||||
if ((p^.flags and IF_WIDE)<>0) <> wideformat then
|
||||
if wideformat and ((p^.flags and IF_WIDE)=0) then
|
||||
begin
|
||||
{matches:=0;
|
||||
exit;}
|
||||
matches:=0;
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ Check that no spurious colons or TOs are present }
|
||||
@ -4079,14 +4126,27 @@ implementation
|
||||
if oper[0]^.typ=top_const then
|
||||
begin
|
||||
if insentry^.code[0]=#$63 then
|
||||
bytes:=bytes or ((oper[0]^.val shr 1) and $FF)
|
||||
bytes:=bytes or (((oper[0]^.val shr 1)-1) and $FF)
|
||||
else
|
||||
bytes:=bytes or ((oper[0]^.val shr 1) and $3FF);
|
||||
bytes:=bytes or (((oper[0]^.val shr 1)-1) and $3FF);
|
||||
end
|
||||
else if oper[0]^.typ=top_reg then
|
||||
begin
|
||||
bytes:=bytes or (getsupreg(oper[0]^.reg) shl 3);
|
||||
end;
|
||||
end
|
||||
else if oper[0]^.typ=top_ref then
|
||||
begin
|
||||
offset:=0;
|
||||
currsym:=objdata.symbolref(oper[0]^.ref^.symbol);
|
||||
if assigned(currsym) then
|
||||
offset:=currsym.offset-insoffset-8;
|
||||
offset:=offset+oper[0]^.ref^.offset;
|
||||
|
||||
if insentry^.code[0]=#$63 then
|
||||
bytes:=bytes or (((offset+4) shr 1) and $FF)
|
||||
else
|
||||
bytes:=bytes or (((offset+4) shr 1) and $7FF);
|
||||
end
|
||||
end;
|
||||
#$64: { Thumb: Special encodings }
|
||||
begin
|
||||
@ -4171,7 +4231,7 @@ implementation
|
||||
else
|
||||
bytes:=bytes or ((oper[1]^.val shr ord(insentry^.code[3])) and $FF);
|
||||
end;
|
||||
#$68: { Thumb CB{N}Z }
|
||||
#$68: { Thumb CB[N]Z }
|
||||
begin
|
||||
bytelen:=2;
|
||||
bytes:=0;
|
||||
|
@ -145,11 +145,11 @@ reg32,reg32,reg32,shifterop \x6\x0\x00 ARM32,ARMv4
|
||||
reg32,reg32,immshifter \x7\x2\x00 ARM32,ARMv4
|
||||
|
||||
[Bcc]
|
||||
imm32 \x62\xE0\x0 THUMB,ARMv4T
|
||||
imm24 \x62\xE0\x0 THUMB,ARMv4T
|
||||
immshifter \x62\xE0\x0 THUMB,ARMv4T
|
||||
mem32 \x62\xE0\x0 THUMB,ARMv4T
|
||||
|
||||
imm32 \x63\xD0\x0 THUMB,ARMv4T
|
||||
imm24 \x63\xD0\x0 THUMB,ARMv4T
|
||||
immshifter \x63\xD0\x0 THUMB,ARMv4T
|
||||
mem32 \x63\xD0\x0 THUMB,ARMv4T
|
||||
|
||||
@ -361,6 +361,7 @@ reg32,regf \x10\x01\x0F ARM32,ARMv4
|
||||
[MSRcc]
|
||||
regf,reg32 \x12\x01\x28\xF0 ARM32,ARMv4
|
||||
regf,immshifter \x13\x03\x28\xF0 ARM32,ARMv4
|
||||
regs,immshifter \x13\x03\x28\xF0 ARM32,ARMv4
|
||||
|
||||
[MULcc]
|
||||
reglo,reglo,reglo \x64\x43\x40 THUMB,ARMv4T
|
||||
@ -396,6 +397,8 @@ vreg,reg32,reg32 \x40\xC\x40\xB\x10 ARM32,VFPv2
|
||||
[NOP]
|
||||
void \x61\xBF\x0 THUMB,ARMv6T2
|
||||
void \x2F\x03\x20\xF0\x0 ARM32,ARMv6K
|
||||
; Before ARMv6K use mov r0,r0
|
||||
void \x2F\xE1\xA0\x0\x0 ARM32,ARMv4
|
||||
|
||||
[ORNcc]
|
||||
reg32,reg32,immshifter \x80\xF0\x60\x0\x0 THUMB32,ARMv6T2
|
||||
|
@ -1,2 +1,2 @@
|
||||
{ don't edit, this file is generated from armins.dat }
|
||||
651;
|
||||
653;
|
||||
|
@ -255,7 +255,7 @@
|
||||
(
|
||||
opcode : A_B;
|
||||
ops : 1;
|
||||
optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none);
|
||||
optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none);
|
||||
code : #98#224#0;
|
||||
flags : if_thumb or if_armv4t
|
||||
),
|
||||
@ -276,7 +276,7 @@
|
||||
(
|
||||
opcode : A_B;
|
||||
ops : 1;
|
||||
optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none);
|
||||
optypes : (ot_immediate24,ot_none,ot_none,ot_none,ot_none,ot_none);
|
||||
code : #99#208#0;
|
||||
flags : if_thumb or if_armv4t
|
||||
),
|
||||
@ -1085,6 +1085,13 @@
|
||||
code : #19#3#40#240;
|
||||
flags : if_arm32 or if_armv4
|
||||
),
|
||||
(
|
||||
opcode : A_MSR;
|
||||
ops : 2;
|
||||
optypes : (ot_regs,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none);
|
||||
code : #19#3#40#240;
|
||||
flags : if_arm32 or if_armv4
|
||||
),
|
||||
(
|
||||
opcode : A_MUL;
|
||||
ops : 3;
|
||||
@ -1225,6 +1232,13 @@
|
||||
code : #47#3#32#240#0;
|
||||
flags : if_arm32 or if_armv6k
|
||||
),
|
||||
(
|
||||
opcode : A_NOP;
|
||||
ops : 0;
|
||||
optypes : (ot_none,ot_none,ot_none,ot_none,ot_none,ot_none);
|
||||
code : #47#225#160#0#0;
|
||||
flags : if_arm32 or if_armv4
|
||||
),
|
||||
(
|
||||
opcode : A_ORN;
|
||||
ops : 3;
|
||||
|
@ -591,7 +591,6 @@ unit cpubase;
|
||||
var
|
||||
t : aint;
|
||||
i : longint;
|
||||
imm : byte;
|
||||
begin
|
||||
{Loading 0-255 is simple}
|
||||
if (d and $FF) = d then
|
||||
@ -611,7 +610,7 @@ unit cpubase;
|
||||
result:=false;
|
||||
for i:=1 to 31 do
|
||||
begin
|
||||
t:=RolDWord(imm,i);
|
||||
t:=RolDWord(d,i);
|
||||
if ((t and $FF)=t) and
|
||||
((t and $80)=$80) then
|
||||
begin
|
||||
|
@ -172,6 +172,10 @@ interface
|
||||
{ Darwin asm is using indirect symbols resolving }
|
||||
indsymbol : TObjSymbol;
|
||||
|
||||
{$ifdef ARM}
|
||||
ThumbFunc : boolean;
|
||||
{$endif ARM}
|
||||
|
||||
constructor create(AList:TFPHashObjectList;const AName:string);
|
||||
function address:aword;
|
||||
procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype);
|
||||
@ -233,9 +237,6 @@ interface
|
||||
ExeSection : TExeSection;
|
||||
USed : Boolean;
|
||||
VTRefList : TFPObjectList;
|
||||
{$ifdef ARM}
|
||||
ThumbFunc : boolean;
|
||||
{$endif ARM}
|
||||
constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);virtual;
|
||||
destructor destroy;override;
|
||||
function write(const d;l:aword):aword;
|
||||
@ -1140,10 +1141,6 @@ implementation
|
||||
begin
|
||||
result:=CObjSection.create(FObjSectionList,aname,aalign,aoptions);
|
||||
result.ObjData:=self;
|
||||
{$ifdef ARM}
|
||||
result.ThumbFunc:=ThumbFunc;
|
||||
ThumbFunc:=false;
|
||||
{$endif ARM}
|
||||
end;
|
||||
FCurrObjSec:=result;
|
||||
end;
|
||||
@ -1181,6 +1178,11 @@ implementation
|
||||
result:=TObjSymbol(FObjSymbolList.Find(aname));
|
||||
if not assigned(result) then
|
||||
result:=TObjSymbol.Create(FObjSymbolList,aname);
|
||||
|
||||
{$ifdef ARM}
|
||||
result.ThumbFunc:=ThumbFunc;
|
||||
ThumbFunc:=false;
|
||||
{$endif ARM}
|
||||
end;
|
||||
|
||||
|
||||
|
@ -970,8 +970,7 @@ implementation
|
||||
elfsym.st_value:=objsym.address;
|
||||
|
||||
{$ifdef ARM}
|
||||
if (objsym.typ=AT_FUNCTION) and
|
||||
objsym.objsection.ThumbFunc then
|
||||
if objsym.ThumbFunc then
|
||||
inc(elfsym.st_value);
|
||||
{$endif ARM}
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
{$asmmode gas}
|
||||
{$asmmode divided}
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_MOVE}
|
||||
{$define FPC_SYSTEM_FPC_MOVE}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
{$asmmode gas}
|
||||
{$asmmode divided}
|
||||
|
||||
{$ifndef FPC_SYSTEM_HAS_MOVE}
|
||||
{$define FPC_SYSTEM_FPC_MOVE}
|
||||
|
Loading…
Reference in New Issue
Block a user