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 ppubuildderefimploper(var o:toper);override;
procedure ppuderefoper(var o:toper);override; procedure ppuderefoper(var o:toper);override;
private private
{ pass1 info }
inIT,
lastinIT: boolean;
{ arm version info }
fArmVMask, fArmVMask,
fArmMask : longint; fArmMask : longint;
{ next fields are filled in pass1, so pass2 is faster } { next fields are filled in pass1, so pass2 is faster }
@ -1447,6 +1451,57 @@ implementation
end; end;
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); procedure finalizearmcode(list, listtoinsert: TAsmList);
begin begin
{ Do Thumb-2 16bit -> 32bit transformations } { Do Thumb-2 16bit -> 32bit transformations }
@ -1459,6 +1514,8 @@ implementation
else if GenerateThumbCode then else if GenerateThumbCode then
ensurethumbencodings(list); ensurethumbencodings(list);
gather_it_info(list);
fix_invalid_imms(list); fix_invalid_imms(list);
insertpcrelativedata(list, listtoinsert); insertpcrelativedata(list, listtoinsert);
@ -2111,8 +2168,8 @@ implementation
{ Check wideformat flag } { Check wideformat flag }
if ((p^.flags and IF_WIDE)<>0) <> wideformat then if ((p^.flags and IF_WIDE)<>0) <> wideformat 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 }
@ -2200,8 +2257,8 @@ implementation
if p^.code[0] in [#$60..#$61] then if p^.code[0] in [#$60..#$61] then
begin begin
if (p^.code[0]=#$60) and if (p^.code[0]=#$60) and
((oppostfix<>PF_S) and (((not inIT) and (oppostfix<>PF_S)) or
(condition<>C_None)) then (inIT and (condition=C_None))) then
begin begin
Matches:=0; Matches:=0;
exit; exit;
@ -4189,6 +4246,23 @@ implementation
end; end;
end; 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 } #$80: { Thumb-2: Dataprocessing }
begin begin
bytes:=0; bytes:=0;

View File

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

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 }
636; 651;

View File

@ -1019,7 +1019,7 @@
opcode : A_MOV; opcode : A_MOV;
ops : 2; ops : 2;
optypes : (ot_reg32,ot_reg32,ot_none,ot_none,ot_none,ot_none); 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 flags : if_thumb or if_armv4t
), ),
( (
@ -2832,8 +2832,8 @@
opcode : A_LSL; opcode : A_LSL;
ops : 3; ops : 3;
optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none); optypes : (ot_reg32,ot_reg32,ot_immediateshifter,ot_none,ot_none,ot_none);
code : #130#234#79#0#32; code : #130#234#79#0#0;
flags : if_thumb32 or if_armv6t2 flags : if_thumb32 or if_wide or if_armv6t2
), ),
( (
opcode : A_LSL; opcode : A_LSL;
@ -4039,6 +4039,13 @@
code : #44#3#64; code : #44#3#64;
flags : if_arm32 or if_armv6t2 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; opcode : A_IT;
ops : 1; ops : 1;
@ -4046,6 +4053,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITE;
ops : 1; ops : 1;
@ -4053,6 +4067,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITT;
ops : 1; ops : 1;
@ -4060,6 +4081,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITEE;
ops : 1; ops : 1;
@ -4067,6 +4095,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITTE;
ops : 1; ops : 1;
@ -4074,6 +4109,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITET;
ops : 1; ops : 1;
@ -4081,6 +4123,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITTT;
ops : 1; ops : 1;
@ -4088,6 +4137,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITEEE;
ops : 1; ops : 1;
@ -4095,6 +4151,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITTEE;
ops : 1; ops : 1;
@ -4102,6 +4165,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITETE;
ops : 1; ops : 1;
@ -4109,6 +4179,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITTTE;
ops : 1; ops : 1;
@ -4116,6 +4193,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITEET;
ops : 1; ops : 1;
@ -4123,6 +4207,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITTET;
ops : 1; ops : 1;
@ -4130,6 +4221,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITETT;
ops : 1; ops : 1;
@ -4137,6 +4235,13 @@
code : #254; code : #254;
flags : if_arm32 or if_armv4 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; opcode : A_ITTTT;
ops : 1; ops : 1;

View File

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

View File

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