Added unified assembler syntax mode so it can be selected with $ASMMODE.

Fixed bug in Mov instruction.
Added initial scanning of IT/LastInIT detection for proper instruction selection.
Disabled "wide" format flag detection again for now.

git-svn-id: branches/laksen/armiw@29338 -
This commit is contained in:
Jeppe Johansen 2014-12-27 00:19:09 +00:00
parent 6976af8365
commit cc418eef74
6 changed files with 235 additions and 17 deletions

View File

@ -260,6 +260,10 @@ uses
procedure ppubuildderefimploper(var o:toper);override;
procedure ppuderefoper(var o:toper);override;
private
{ pass1 info }
inIT,
lastinIT: boolean;
{ arm version info }
fArmVMask,
fArmMask : longint;
{ next fields are filled in pass1, so pass2 is faster }
@ -1447,6 +1451,57 @@ implementation
end;
end;
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;
it_count: longint;
begin
in_it:=false;
it_count:=0;
curtai:=tai(list.First);
while assigned(curtai) do
begin
case curtai.typ of
ait_instruction:
begin
case taicpu(curtai).opcode of
A_IT..A_ITTTT:
begin
if in_it then
Message1(asmw_e_invalid_opcode_and_operands, 'ITxx instruction is inside another ITxx instruction')
else
begin
in_it:=true;
it_count:=opCount[taicpu(curtai).opcode];
end;
end;
else
begin
taicpu(curtai).inIT:=in_it;
taicpu(curtai).lastinIT:=in_it and (it_count=1);
if in_it then
begin
dec(it_count);
if it_count <= 0 then
in_it:=false;
end;
end;
end;
end;
end;
curtai:=tai(curtai.Next);
end;
end;
procedure finalizearmcode(list, listtoinsert: TAsmList);
begin
{ Do Thumb-2 16bit -> 32bit transformations }
@ -1459,6 +1514,8 @@ implementation
else if GenerateThumbCode then
ensurethumbencodings(list);
gather_it_info(list);
fix_invalid_imms(list);
insertpcrelativedata(list, listtoinsert);
@ -2111,8 +2168,8 @@ implementation
{ Check wideformat flag }
if ((p^.flags and IF_WIDE)<>0) <> wideformat then
begin
matches:=0;
exit;
{matches:=0;
exit;}
end;
{ Check that no spurious colons or TOs are present }
@ -2200,8 +2257,8 @@ implementation
if p^.code[0] in [#$60..#$61] then
begin
if (p^.code[0]=#$60) and
((oppostfix<>PF_S) and
(condition<>C_None)) then
(((not inIT) and (oppostfix<>PF_S)) or
(inIT and (condition=C_None))) then
begin
Matches:=0;
exit;
@ -4189,6 +4246,23 @@ implementation
end;
end;
end;
#$6A: { Thumb: IT }
begin
bytelen:=2;
bytes:=0;
{ set opcode }
bytes:=bytes or (ord(insentry^.code[1]) shl 8);
bytes:=bytes or (ord(insentry^.code[2]) shl 0);
bytes:=bytes or (CondVal[oper[0]^.cc] shl 4);
i_field:=(bytes shr 4) and 1;
i_field:=(i_field shl 1) or i_field;
i_field:=(i_field shl 2) or i_field;
bytes:=bytes or ((i_field and ord(insentry^.code[3])) xor (ord(insentry^.code[3]) shr 4));
end;
#$80: { Thumb-2: Dataprocessing }
begin
bytes:=0;

View File

@ -343,7 +343,7 @@ reg32,reg32,reg32,reg32 \x15\x00\x20\x9 ARM32,ARMv4
[MOVcc]
reglo,reglo \x60\x0\x0 THUMB,ARMv4T
reg32,reg32 \x61\x46\xC0 THUMB,ARMv4T
reg32,reg32 \x61\x46\x00 THUMB,ARMv4T
reglo,immshifter \x60\x20\x0 THUMB,ARMv4T
@ -839,7 +839,7 @@ reg32,reg32,immshifter \x30\x1\xA0\x0\x20 ARM32,ARMv4
reglo,reglo,immshifter \x60\x0\x0 THUMB,ARMv4T
reglo,reglo \x60\x40\x80 THUMB,ARMv4T
reg32,reg32,immshifter \x82\xEA\x4F\x0\x20 THUMB32,ARMv6T2
reg32,reg32,immshifter \x82\xEA\x4F\x0\x00 THUMB32,WIDE,ARMv6T2
reg32,reg32,reg32 \x80\xFA\x60\xF0\x0 THUMB32,WIDE,ARMv6T2
reg32,reg32,reg32 \x30\x1\xA0\x0\x10 ARM32,ARMv4
@ -1292,48 +1292,63 @@ reg32,imm \x2C\x3\x40 ARM32,ARMv6T2
reg32,immshifter \x2C\x3\x40 ARM32,ARMv6T2
[IT]
condition \x6A\xBF\x08\x00 THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITE]
condition \x6A\xBF\x04\x88 THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITT]
condition \x6A\xBF\x04\x08 THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITEE]
condition \x6A\xBF\x02\xCC THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITTE]
condition \x6A\xBF\x02\x4C THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITET]
condition \x6A\xBF\x02\x8C THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITTT]
condition \x6A\xBF\x02\x0C THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITEEE]
condition \x6A\xBF\x01\xEE THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITTEE]
condition \x6A\xBF\x01\x6E THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITETE]
condition \x6A\xBF\x01\xAE THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITTTE]
condition \x6A\xBF\x01\x2E THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITEET]
condition \x6A\xBF\x01\xCE THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITTET]
condition \x6A\xBF\x01\x4E THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITETT]
condition \x6A\xBF\x01\x8E THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[ITTTT]
condition \x6A\xBF\x01\x0E THUMB,ARMv6T2
condition \xFE ARM32,ARMv4
[TBB]

View File

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

View File

@ -1019,7 +1019,7 @@
opcode : A_MOV;
ops : 2;
optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none);
code : #97#70#192;
code : #97#70#0;
flags : if_thumb or if_armv4t
),
(
@ -2832,8 +2832,8 @@
opcode : A_LSL;
ops : 3;
optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none);
code : #130#234#79#0#32;
flags : if_thumb32 or if_armv6t2
code : #130#234#79#0#0;
flags : if_thumb32 or if_wide or if_armv6t2
),
(
opcode : A_LSL;
@ -4039,6 +4039,13 @@
code : #44#3#64;
flags : if_arm32 or if_armv6t2
),
(
opcode : A_IT;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#8#0;
flags : if_thumb or if_armv6t2
),
(
opcode : A_IT;
ops : 1;
@ -4046,6 +4053,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITE;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#4#136;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITE;
ops : 1;
@ -4053,6 +4067,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITT;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#4#8;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITT;
ops : 1;
@ -4060,6 +4081,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITEE;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#2#204;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITEE;
ops : 1;
@ -4067,6 +4095,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITTE;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#2#76;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITTE;
ops : 1;
@ -4074,6 +4109,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITET;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#2#140;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITET;
ops : 1;
@ -4081,6 +4123,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITTT;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#2#12;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITTT;
ops : 1;
@ -4088,6 +4137,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITEEE;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#1#238;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITEEE;
ops : 1;
@ -4095,6 +4151,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITTEE;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#1#110;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITTEE;
ops : 1;
@ -4102,6 +4165,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITETE;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#1#174;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITETE;
ops : 1;
@ -4109,6 +4179,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITTTE;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#1#46;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITTTE;
ops : 1;
@ -4116,6 +4193,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITEET;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#1#206;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITEET;
ops : 1;
@ -4123,6 +4207,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITTET;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#1#78;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITTET;
ops : 1;
@ -4130,6 +4221,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITETT;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#1#142;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITETT;
ops : 1;
@ -4137,6 +4235,13 @@
code : #254;
flags : if_arm32 or if_armv4
),
(
opcode : A_ITTTT;
ops : 1;
optypes : (ot_condition,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #106#191#1#14;
flags : if_thumb or if_armv6t2
),
(
opcode : A_ITTTT;
ops : 1;

View File

@ -30,10 +30,8 @@ Unit raarmgas;
cpubase;
type
tarmsyntax = (asm_legacy, asm_unified);
tarmattreader = class(tattreader)
asmsyntax : tarmsyntax;
actoppostfix : TOpPostfix;
actwideformat : boolean;
function is_asmopcode(const s: string):boolean;override;
@ -48,6 +46,13 @@ Unit raarmgas;
procedure ReadSym(oper : tarmoperand);
procedure ConvertCalljmp(instr : tarminstruction);
procedure HandleTargetDirective; override;
protected
function is_unified: boolean; virtual;
end;
tarmunifiedattreader = class(tarmattreader)
protected
function is_unified: boolean; override;
end;
@ -66,6 +71,12 @@ Unit raarmgas;
cgbase,cgutils;
function tarmunifiedattreader.is_unified: boolean;
begin
result:=true;
end;
function tarmattreader.is_register(const s:string):boolean;
type
treg2str = record
@ -1294,10 +1305,11 @@ Unit raarmgas;
end;
dec(j2);
end;
if actopcode=A_NONE then
exit;
if asmsyntax=asm_unified then
if is_unified then
begin
{ check for postfix }
if (length(hs)>0) and (actoppostfix=PF_None) then
@ -1431,12 +1443,17 @@ Unit raarmgas;
else if actasmpattern='.thumb_func' then
begin
consume(AS_TARGET_DIRECTIVE);
curList.concat(tai_thumb_func.create);
curList.concat(tai_directive.create(asd_thumb_func,''));
end
else
inherited HandleTargetDirective;
end;
function tarmattreader.is_unified: boolean;
begin
result:=false;
end;
procedure tarmattreader.handleopcode;
var
@ -1455,8 +1472,6 @@ Unit raarmgas;
instr.Free;
actoppostfix:=PF_None;
actwideformat:=false;
asmsyntax:=asm_legacy;
end;
@ -1468,10 +1483,17 @@ const
asmmode_arm_att_info : tasmmodeinfo =
(
id : asmmode_arm_gas;
idtxt : 'GAS';
idtxt : 'DIVIDED';
casmreader : tarmattreader;
);
asmmode_arm_att_unified_info : tasmmodeinfo =
(
id : asmmode_arm_gas_unified;
idtxt : 'UNIFIED';
casmreader : tarmunifiedattreader;
);
asmmode_arm_standard_info : tasmmodeinfo =
(
id : asmmode_standard;
@ -1481,5 +1503,6 @@ const
initialization
RegisterAsmMode(asmmode_arm_att_info);
RegisterAsmMode(asmmode_arm_att_unified_info);
RegisterAsmMode(asmmode_arm_standard_info);
end.

View File

@ -68,6 +68,7 @@
,asmmode_avr_gas
,asmmode_i8086_intel
,asmmode_i8086_att
,asmmode_arm_gas_unified
);
(* IMPORTANT NOTE: