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:
Jeppe Johansen 2014-12-27 13:23:02 +00:00
parent de00a1d76d
commit 71cdedea82
9 changed files with 107 additions and 30 deletions

View File

@ -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;

View File

@ -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

View File

@ -1,2 +1,2 @@
{ don't edit, this file is generated from armins.dat }
651;
653;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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}

View File

@ -15,7 +15,7 @@
**********************************************************************}
{$asmmode gas}
{$asmmode divided}
{$ifndef FPC_SYSTEM_HAS_MOVE}
{$define FPC_SYSTEM_FPC_MOVE}

View File

@ -15,7 +15,7 @@
**********************************************************************}
{$asmmode gas}
{$asmmode divided}
{$ifndef FPC_SYSTEM_HAS_MOVE}
{$define FPC_SYSTEM_FPC_MOVE}