Refactor and secure some immediate operand encodings.

Add some system mode entries, udiv/sdiv in arm mode, and fix bugs in ldrh/strh.

git-svn-id: branches/laksen/armiw@29353 -
This commit is contained in:
Jeppe Johansen 2014-12-28 21:41:06 +00:00
parent e7575d9f96
commit 9a482d5281
5 changed files with 108 additions and 53 deletions

View File

@ -113,6 +113,7 @@ uses
OT_AMMASK = $001f0000;
{ IT instruction }
OT_CONDITION = $00200000;
OT_MODEFLAGS = $00400000;
OT_MEMORYAM2 = OT_MEMORY or OT_AM2;
OT_MEMORYAM3 = OT_MEMORY or OT_AM3;
@ -2188,6 +2189,10 @@ implementation
begin
ot:=OT_REGS;
end;
top_modeflags:
begin
ot:=OT_MODEFLAGS;
end;
else
begin writeln(typ);
internalerror(200402261); end;
@ -2863,6 +2868,10 @@ implementation
case oper[1]^.reg of
NR_APSR,NR_CPSR:;
NR_SPSR:
begin
bytes:=bytes or (1 shl 22);
end;
else
Message(asmw_e_invalid_opcode_and_operands);
end;
@ -2877,13 +2886,22 @@ implementation
if oper[0]^.typ=top_specialreg then
begin
if oper[0]^.specialreg<>NR_CPSR then
Message1(asmw_e_invalid_opcode_and_operands, 'Can only use CPSR in this form');
if (oper[0]^.specialreg<>NR_CPSR) and
(oper[0]^.specialreg<>NR_SPSR) then
Message1(asmw_e_invalid_opcode_and_operands, '"Invalid special reg"');
if srF in oper[0]^.specialflags then
bytes:=bytes or (2 shl 18);
if srC in oper[0]^.specialflags then
bytes:=bytes or (1 shl 16);
if srX in oper[0]^.specialflags then
bytes:=bytes or (1 shl 17);
if srS in oper[0]^.specialflags then
bytes:=bytes or (1 shl 18);
if srF in oper[0]^.specialflags then
bytes:=bytes or (1 shl 19);
{ Set R bit }
if oper[0]^.specialreg=NR_SPSR then
bytes:=bytes or (1 shl 22);
end
else
case oper[0]^.reg of
@ -3002,16 +3020,11 @@ implementation
offset:=currsym.offset-insoffset-8;
offset:=offset+oper[1]^.ref^.offset;
if offset>=0 then
begin
{ set U flag }
bytes:=bytes or (1 shl 23);
bytes:=bytes or offset
end
{ set U flag }
bytes:=bytes or (1 shl 23)
else
begin
offset:=-offset;
bytes:=bytes or offset
end;
offset:=-offset;
bytes:=bytes or (offset and $FFF);
end
else
begin
@ -3090,18 +3103,12 @@ implementation
offset:=currsym.offset-insoffset-8;
offset:=offset+refoper^.ref^.offset;
if offset>=0 then
begin
{ set U flag }
bytes:=bytes or (1 shl 23);
bytes:=bytes or (offset and $F);
bytes:=bytes or ((offset and $F0) shl 4);
end
{ set U flag }
bytes:=bytes or (1 shl 23)
else
begin
offset:=-offset;
bytes:=bytes or (offset and $F);
bytes:=bytes or ((offset and $F0) shl 4);
end;
offset:=-offset;
bytes:=bytes or (offset and $F);
bytes:=bytes or ((offset and $F0) shl 4);
end
else
begin
@ -3197,19 +3204,14 @@ implementation
if assigned(currsym) then
offset:=currsym.offset-insoffset-8;
offset:=offset+refoper^.ref^.offset;
if offset>=0 then
begin
{ set U flag }
bytes:=bytes or (1 shl 23);
bytes:=bytes or (offset and $F);
bytes:=bytes or ((offset and $F0) shl 4);
end
{ set U flag }
bytes:=bytes or (1 shl 23)
else
begin
offset:=-offset;
bytes:=bytes or (offset and $F);
bytes:=bytes or ((offset and $F0) shl 4);
end;
offset:=-offset;
bytes:=bytes or (offset and $F);
bytes:=bytes or ((offset and $F0) shl 4);
end
else
begin
@ -3231,18 +3233,14 @@ implementation
if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then
begin
bytes:=bytes or (1 shl 22); // with immediate offset
if oper[1]^.ref^.offset < 0 then
begin
bytes:=bytes or ((-oper[1]^.ref^.offset) and $f0 shl 4);
bytes:=bytes or ((-oper[1]^.ref^.offset) and $f);
end
offset:=oper[1]^.ref^.offset;
if offset>=0 then
{ set U flag }
bytes:=bytes or (1 shl 23)
else
begin
{ set U bit }
bytes:=bytes or (1 shl 23);
bytes:=bytes or (oper[1]^.ref^.offset and $f0 shl 4);
bytes:=bytes or (oper[1]^.ref^.offset and $f);
end;
offset:=-offset;
bytes:=bytes or (offset and $F);
bytes:=bytes or ((offset and $F0) shl 4);
end
else
begin

View File

@ -375,9 +375,9 @@ reg32,immshifter \xB\x1\xA0 ARM32,ARMv4
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
regf,reg32 \x12\x01\x20\xF0 ARM32,ARMv4
regf,immshifter \x13\x03\x20\xF0 ARM32,ARMv4
regs,immshifter \x13\x03\x20\xF0 ARM32,ARMv4
[MULcc]
reglo,reglo \x64\x43\x40 THUMB,ARMv4T
@ -647,8 +647,12 @@ reg32,reg32,reg32,reg32 \x16\x01\x40\xA ARM32,ARMv5TE
reg32,reg32,reg32,reg32 \x16\x01\x40\xE ARM32,ARMv5TE
[SMLAWBcc]
reg32,reg32,reg32,reg32 \x80\xFB\x30\x0\x00 THUMB32,ARMv6T2
reg32,reg32,reg32,reg32 \x15\x1\x20\x8 ARM32,ARMv5TE
[SMLAWTcc]
reg32,reg32,reg32,reg32 \x80\xFB\x30\x0\x10 THUMB32,ARMv6T2
reg32,reg32,reg32,reg32 \x15\x1\x20\xC ARM32,ARMv5TE
[VLDMcc]
memam4,reglist \x44\xC\x10\xA ARM32,VFPv2
@ -1331,9 +1335,11 @@ reglist \x26\x80 ARM32,ARMv4
[SDIVcc]
reg32,reg32,reg32 \x80\xFB\x90\xF0\xF0 THUMB32,ARMv7R,ARMv7M
reg32,reg32,reg32 \x15\x07\x10\x01\xF ARM32,ARMv7
[UDIVcc]
reg32,reg32,reg32 \x80\xFB\xB0\xF0\xF0 THUMB32,ARMv7R,ARMv7M
reg32,reg32,reg32 \x15\x07\x30\x01\xF ARM32,ARMv7
[MOVTcc]
reg32,imm \x81\xF2\xC0\x0\x0 THUMB32,ARMv6T2
@ -1501,6 +1507,7 @@ immshifter \x2E\xF5\x7F\xF0\x40 ARM32,ARMv7
[SMC]
immshifter \x2E\x01\x60\x00\x70 ARM32,ARMv7
imm32 \x2E\x01\x60\x00\x70 ARM32,ARMv7
; Thumb armv6-m (gcc)
[NEG]

View File

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

View File

@ -1187,21 +1187,21 @@
opcode : A_MSR;
ops : 2;
optypes : (ot_regf,ot_reg32,ot_none,ot_none,ot_none,ot_none);
code : #18#1#40#240;
code : #18#1#32#240;
flags : if_arm32 or if_armv4
),
(
opcode : A_MSR;
ops : 2;
optypes : (ot_regf,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none);
code : #19#3#40#240;
code : #19#3#32#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;
code : #19#3#32#240;
flags : if_arm32 or if_armv4
),
(
@ -2310,6 +2310,34 @@
code : #22#1#64#14;
flags : if_arm32 or if_armv5te
),
(
opcode : A_SMLAWB;
ops : 4;
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none);
code : #128#251#48#0#0;
flags : if_thumb32 or if_armv6t2
),
(
opcode : A_SMLAWB;
ops : 4;
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none);
code : #21#1#32#8;
flags : if_arm32 or if_armv5te
),
(
opcode : A_SMLAWT;
ops : 4;
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none);
code : #128#251#48#0#16;
flags : if_thumb32 or if_armv6t2
),
(
opcode : A_SMLAWT;
ops : 4;
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none);
code : #21#1#32#12;
flags : if_arm32 or if_armv5te
),
(
opcode : A_VLDM;
ops : 2;
@ -4354,6 +4382,13 @@
code : #128#251#144#240#240;
flags : if_thumb32 or if_armv7r or if_armv7m
),
(
opcode : A_SDIV;
ops : 3;
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none);
code : #21#7#16#1#15;
flags : if_arm32 or if_armv7
),
(
opcode : A_UDIV;
ops : 3;
@ -4361,6 +4396,13 @@
code : #128#251#176#240#240;
flags : if_thumb32 or if_armv7r or if_armv7m
),
(
opcode : A_UDIV;
ops : 3;
optypes : (ot_reg32,ot_reg32,ot_reg32,ot_none,ot_none,ot_none);
code : #21#7#48#1#15;
flags : if_arm32 or if_armv7
),
(
opcode : A_MOVT;
ops : 2;
@ -4872,6 +4914,13 @@
code : #46#1#96#0#112;
flags : if_arm32 or if_armv7
),
(
opcode : A_SMC;
ops : 1;
optypes : (ot_immediate or ot_bits32,ot_none,ot_none,ot_none,ot_none,ot_none);
code : #46#1#96#0#112;
flags : if_arm32 or if_armv7
),
(
opcode : A_SVC;
ops : 1;

View File

@ -1190,6 +1190,7 @@ Unit raarmgas;
((operandnum=3) and not(instr.opcode in [A_UMLAL,A_UMULL,A_SMLAL,A_SMULL,A_MLA,A_UMAAL,A_MLS,
A_SMLABB,A_SMLABT,A_SMLATB,A_SMLATT,A_SMMLA,A_SMMLS,A_SMLAD,A_SMLALD,A_SMLSD,
A_SMLALBB,A_SMLALBT,A_SMLALTB,A_SMLALTT,A_SMLSLD,
A_SMLAWB,A_SMLAWT,
A_MRC,A_MCR,A_MCRR,A_MRRC,A_MRC2,A_MCR2,A_MCRR2,A_MRRC2,
A_STREXD,A_STRD,
A_USADA8,