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_REG64 = $00201008;
OT_VREG = $00201010; { vector register } OT_VREG = $00201010; { vector register }
OT_REGF = $00201020; { coproc register } OT_REGF = $00201020; { coproc register }
OT_REGS = $00201040; { special register with mask }
OT_MEMORY = $00204000; { register number in 'basereg' } OT_MEMORY = $00204000; { register number in 'basereg' }
OT_MEM8 = $00204001; OT_MEM8 = $00204001;
OT_MEM16 = $00204002; OT_MEM16 = $00204002;
@ -1453,10 +1454,6 @@ implementation
procedure gather_it_info(list: TAsmList); 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 var
curtai: tai; curtai: tai;
in_it: boolean; in_it: boolean;
@ -1479,7 +1476,7 @@ implementation
else else
begin begin
in_it:=true; in_it:=true;
it_count:=opCount[taicpu(curtai).opcode]; it_count:=GetITLevels(taicpu(curtai).opcode);
end; end;
end; end;
else else
@ -1502,8 +1499,51 @@ implementation
end; end;
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); procedure finalizearmcode(list, listtoinsert: TAsmList);
begin begin
expand_instructions(list);
{ Do Thumb-2 16bit -> 32bit transformations } { Do Thumb-2 16bit -> 32bit transformations }
if GenerateThumb2Code then if GenerateThumb2Code then
begin begin
@ -1712,6 +1752,9 @@ implementation
else else
if (ot and OT_FPUREG)=OT_FPUREG then if (ot and OT_FPUREG)=OT_FPUREG then
s:=s+'fpureg' s:=s+'fpureg'
else
if (ot and OT_REGS)=OT_REGS then
s:=s+'sreg'
else else
if (ot and OT_REGF)=OT_REGF then if (ot and OT_REGF)=OT_REGF then
s:=s+'creg' s:=s+'creg'
@ -2109,6 +2152,10 @@ implementation
begin begin
ot:=OT_CONDITION; ot:=OT_CONDITION;
end; end;
top_specialreg:
begin
ot:=OT_REGS;
end;
else else
begin writeln(typ); begin writeln(typ);
internalerror(200402261); end; internalerror(200402261); end;
@ -2166,10 +2213,10 @@ implementation
end; end;
{ Check wideformat flag } { Check wideformat flag }
if ((p^.flags and IF_WIDE)<>0) <> wideformat then if wideformat and ((p^.flags and IF_WIDE)=0) then
begin begin
{matches:=0; matches:=0;
exit;} exit;
end; end;
{ Check that no spurious colons or TOs are present } { Check that no spurious colons or TOs are present }
@ -4079,14 +4126,27 @@ implementation
if oper[0]^.typ=top_const then if oper[0]^.typ=top_const then
begin begin
if insentry^.code[0]=#$63 then 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 else
bytes:=bytes or ((oper[0]^.val shr 1) and $3FF); bytes:=bytes or (((oper[0]^.val shr 1)-1) and $3FF);
end end
else if oper[0]^.typ=top_reg then else if oper[0]^.typ=top_reg then
begin begin
bytes:=bytes or (getsupreg(oper[0]^.reg) shl 3); 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; end;
#$64: { Thumb: Special encodings } #$64: { Thumb: Special encodings }
begin begin
@ -4171,7 +4231,7 @@ implementation
else else
bytes:=bytes or ((oper[1]^.val shr ord(insentry^.code[3])) and $FF); bytes:=bytes or ((oper[1]^.val shr ord(insentry^.code[3])) and $FF);
end; end;
#$68: { Thumb CB{N}Z } #$68: { Thumb CB[N]Z }
begin begin
bytelen:=2; bytelen:=2;
bytes:=0; 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 reg32,reg32,immshifter \x7\x2\x00 ARM32,ARMv4
[Bcc] [Bcc]
imm32 \x62\xE0\x0 THUMB,ARMv4T imm24 \x62\xE0\x0 THUMB,ARMv4T
immshifter \x62\xE0\x0 THUMB,ARMv4T immshifter \x62\xE0\x0 THUMB,ARMv4T
mem32 \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 immshifter \x63\xD0\x0 THUMB,ARMv4T
mem32 \x63\xD0\x0 THUMB,ARMv4T mem32 \x63\xD0\x0 THUMB,ARMv4T
@ -361,6 +361,7 @@ reg32,regf \x10\x01\x0F ARM32,ARMv4
[MSRcc] [MSRcc]
regf,reg32 \x12\x01\x28\xF0 ARM32,ARMv4 regf,reg32 \x12\x01\x28\xF0 ARM32,ARMv4
regf,immshifter \x13\x03\x28\xF0 ARM32,ARMv4 regf,immshifter \x13\x03\x28\xF0 ARM32,ARMv4
regs,immshifter \x13\x03\x28\xF0 ARM32,ARMv4
[MULcc] [MULcc]
reglo,reglo,reglo \x64\x43\x40 THUMB,ARMv4T reglo,reglo,reglo \x64\x43\x40 THUMB,ARMv4T
@ -396,6 +397,8 @@ vreg,reg32,reg32 \x40\xC\x40\xB\x10 ARM32,VFPv2
[NOP] [NOP]
void \x61\xBF\x0 THUMB,ARMv6T2 void \x61\xBF\x0 THUMB,ARMv6T2
void \x2F\x03\x20\xF0\x0 ARM32,ARMv6K void \x2F\x03\x20\xF0\x0 ARM32,ARMv6K
; Before ARMv6K use mov r0,r0
void \x2F\xE1\xA0\x0\x0 ARM32,ARMv4
[ORNcc] [ORNcc]
reg32,reg32,immshifter \x80\xF0\x60\x0\x0 THUMB32,ARMv6T2 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 } { don't edit, this file is generated from armins.dat }
651; 653;

View File

@ -255,7 +255,7 @@
( (
opcode : A_B; opcode : A_B;
ops : 1; 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; code : #98#224#0;
flags : if_thumb or if_armv4t flags : if_thumb or if_armv4t
), ),
@ -276,7 +276,7 @@
( (
opcode : A_B; opcode : A_B;
ops : 1; 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; code : #99#208#0;
flags : if_thumb or if_armv4t flags : if_thumb or if_armv4t
), ),
@ -1085,6 +1085,13 @@
code : #19#3#40#240; code : #19#3#40#240;
flags : if_arm32 or if_armv4 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; opcode : A_MUL;
ops : 3; ops : 3;
@ -1225,6 +1232,13 @@
code : #47#3#32#240#0; code : #47#3#32#240#0;
flags : if_arm32 or if_armv6k 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; opcode : A_ORN;
ops : 3; ops : 3;

View File

@ -591,7 +591,6 @@ unit cpubase;
var var
t : aint; t : aint;
i : longint; i : longint;
imm : byte;
begin begin
{Loading 0-255 is simple} {Loading 0-255 is simple}
if (d and $FF) = d then if (d and $FF) = d then
@ -611,7 +610,7 @@ unit cpubase;
result:=false; result:=false;
for i:=1 to 31 do for i:=1 to 31 do
begin begin
t:=RolDWord(imm,i); t:=RolDWord(d,i);
if ((t and $FF)=t) and if ((t and $FF)=t) and
((t and $80)=$80) then ((t and $80)=$80) then
begin begin

View File

@ -172,6 +172,10 @@ interface
{ Darwin asm is using indirect symbols resolving } { Darwin asm is using indirect symbols resolving }
indsymbol : TObjSymbol; indsymbol : TObjSymbol;
{$ifdef ARM}
ThumbFunc : boolean;
{$endif ARM}
constructor create(AList:TFPHashObjectList;const AName:string); constructor create(AList:TFPHashObjectList;const AName:string);
function address:aword; function address:aword;
procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype); procedure SetAddress(apass:byte;aobjsec:TObjSection;abind:TAsmsymbind;atyp:Tasmsymtype);
@ -233,9 +237,6 @@ interface
ExeSection : TExeSection; ExeSection : TExeSection;
USed : Boolean; USed : Boolean;
VTRefList : TFPObjectList; VTRefList : TFPObjectList;
{$ifdef ARM}
ThumbFunc : boolean;
{$endif ARM}
constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);virtual; constructor create(AList:TFPHashObjectList;const Aname:string;Aalign:shortint;Aoptions:TObjSectionOptions);virtual;
destructor destroy;override; destructor destroy;override;
function write(const d;l:aword):aword; function write(const d;l:aword):aword;
@ -1140,10 +1141,6 @@ implementation
begin begin
result:=CObjSection.create(FObjSectionList,aname,aalign,aoptions); result:=CObjSection.create(FObjSectionList,aname,aalign,aoptions);
result.ObjData:=self; result.ObjData:=self;
{$ifdef ARM}
result.ThumbFunc:=ThumbFunc;
ThumbFunc:=false;
{$endif ARM}
end; end;
FCurrObjSec:=result; FCurrObjSec:=result;
end; end;
@ -1181,6 +1178,11 @@ implementation
result:=TObjSymbol(FObjSymbolList.Find(aname)); result:=TObjSymbol(FObjSymbolList.Find(aname));
if not assigned(result) then if not assigned(result) then
result:=TObjSymbol.Create(FObjSymbolList,aname); result:=TObjSymbol.Create(FObjSymbolList,aname);
{$ifdef ARM}
result.ThumbFunc:=ThumbFunc;
ThumbFunc:=false;
{$endif ARM}
end; end;

View File

@ -970,8 +970,7 @@ implementation
elfsym.st_value:=objsym.address; elfsym.st_value:=objsym.address;
{$ifdef ARM} {$ifdef ARM}
if (objsym.typ=AT_FUNCTION) and if objsym.ThumbFunc then
objsym.objsection.ThumbFunc then
inc(elfsym.st_value); inc(elfsym.st_value);
{$endif ARM} {$endif ARM}

View File

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

View File

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