mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 13:29:15 +02:00
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:
parent
e7575d9f96
commit
9a482d5281
@ -113,6 +113,7 @@ uses
|
|||||||
OT_AMMASK = $001f0000;
|
OT_AMMASK = $001f0000;
|
||||||
{ IT instruction }
|
{ IT instruction }
|
||||||
OT_CONDITION = $00200000;
|
OT_CONDITION = $00200000;
|
||||||
|
OT_MODEFLAGS = $00400000;
|
||||||
|
|
||||||
OT_MEMORYAM2 = OT_MEMORY or OT_AM2;
|
OT_MEMORYAM2 = OT_MEMORY or OT_AM2;
|
||||||
OT_MEMORYAM3 = OT_MEMORY or OT_AM3;
|
OT_MEMORYAM3 = OT_MEMORY or OT_AM3;
|
||||||
@ -2188,6 +2189,10 @@ implementation
|
|||||||
begin
|
begin
|
||||||
ot:=OT_REGS;
|
ot:=OT_REGS;
|
||||||
end;
|
end;
|
||||||
|
top_modeflags:
|
||||||
|
begin
|
||||||
|
ot:=OT_MODEFLAGS;
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
begin writeln(typ);
|
begin writeln(typ);
|
||||||
internalerror(200402261); end;
|
internalerror(200402261); end;
|
||||||
@ -2863,6 +2868,10 @@ implementation
|
|||||||
|
|
||||||
case oper[1]^.reg of
|
case oper[1]^.reg of
|
||||||
NR_APSR,NR_CPSR:;
|
NR_APSR,NR_CPSR:;
|
||||||
|
NR_SPSR:
|
||||||
|
begin
|
||||||
|
bytes:=bytes or (1 shl 22);
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
Message(asmw_e_invalid_opcode_and_operands);
|
Message(asmw_e_invalid_opcode_and_operands);
|
||||||
end;
|
end;
|
||||||
@ -2877,13 +2886,22 @@ implementation
|
|||||||
|
|
||||||
if oper[0]^.typ=top_specialreg then
|
if oper[0]^.typ=top_specialreg then
|
||||||
begin
|
begin
|
||||||
if oper[0]^.specialreg<>NR_CPSR then
|
if (oper[0]^.specialreg<>NR_CPSR) and
|
||||||
Message1(asmw_e_invalid_opcode_and_operands, 'Can only use CPSR in this form');
|
(oper[0]^.specialreg<>NR_SPSR) then
|
||||||
|
Message1(asmw_e_invalid_opcode_and_operands, '"Invalid special reg"');
|
||||||
|
|
||||||
if srF in oper[0]^.specialflags then
|
if srC in oper[0]^.specialflags then
|
||||||
bytes:=bytes or (2 shl 18);
|
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
|
if srS in oper[0]^.specialflags then
|
||||||
bytes:=bytes or (1 shl 18);
|
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
|
end
|
||||||
else
|
else
|
||||||
case oper[0]^.reg of
|
case oper[0]^.reg of
|
||||||
@ -3002,16 +3020,11 @@ implementation
|
|||||||
offset:=currsym.offset-insoffset-8;
|
offset:=currsym.offset-insoffset-8;
|
||||||
offset:=offset+oper[1]^.ref^.offset;
|
offset:=offset+oper[1]^.ref^.offset;
|
||||||
if offset>=0 then
|
if offset>=0 then
|
||||||
begin
|
{ set U flag }
|
||||||
{ set U flag }
|
bytes:=bytes or (1 shl 23)
|
||||||
bytes:=bytes or (1 shl 23);
|
|
||||||
bytes:=bytes or offset
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
offset:=-offset;
|
||||||
offset:=-offset;
|
bytes:=bytes or (offset and $FFF);
|
||||||
bytes:=bytes or offset
|
|
||||||
end;
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -3090,18 +3103,12 @@ implementation
|
|||||||
offset:=currsym.offset-insoffset-8;
|
offset:=currsym.offset-insoffset-8;
|
||||||
offset:=offset+refoper^.ref^.offset;
|
offset:=offset+refoper^.ref^.offset;
|
||||||
if offset>=0 then
|
if offset>=0 then
|
||||||
begin
|
{ set U flag }
|
||||||
{ set U flag }
|
bytes:=bytes or (1 shl 23)
|
||||||
bytes:=bytes or (1 shl 23);
|
|
||||||
bytes:=bytes or (offset and $F);
|
|
||||||
bytes:=bytes or ((offset and $F0) shl 4);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
offset:=-offset;
|
||||||
offset:=-offset;
|
bytes:=bytes or (offset and $F);
|
||||||
bytes:=bytes or (offset and $F);
|
bytes:=bytes or ((offset and $F0) shl 4);
|
||||||
bytes:=bytes or ((offset and $F0) shl 4);
|
|
||||||
end;
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -3197,19 +3204,14 @@ implementation
|
|||||||
if assigned(currsym) then
|
if assigned(currsym) then
|
||||||
offset:=currsym.offset-insoffset-8;
|
offset:=currsym.offset-insoffset-8;
|
||||||
offset:=offset+refoper^.ref^.offset;
|
offset:=offset+refoper^.ref^.offset;
|
||||||
|
|
||||||
if offset>=0 then
|
if offset>=0 then
|
||||||
begin
|
{ set U flag }
|
||||||
{ set U flag }
|
bytes:=bytes or (1 shl 23)
|
||||||
bytes:=bytes or (1 shl 23);
|
|
||||||
bytes:=bytes or (offset and $F);
|
|
||||||
bytes:=bytes or ((offset and $F0) shl 4);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
offset:=-offset;
|
||||||
offset:=-offset;
|
bytes:=bytes or (offset and $F);
|
||||||
bytes:=bytes or (offset and $F);
|
bytes:=bytes or ((offset and $F0) shl 4);
|
||||||
bytes:=bytes or ((offset and $F0) shl 4);
|
|
||||||
end;
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -3231,18 +3233,14 @@ implementation
|
|||||||
if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then
|
if getregtype(oper[1]^.ref^.index)=R_INVALIDREGISTER then
|
||||||
begin
|
begin
|
||||||
bytes:=bytes or (1 shl 22); // with immediate offset
|
bytes:=bytes or (1 shl 22); // with immediate offset
|
||||||
if oper[1]^.ref^.offset < 0 then
|
offset:=oper[1]^.ref^.offset;
|
||||||
begin
|
if offset>=0 then
|
||||||
bytes:=bytes or ((-oper[1]^.ref^.offset) and $f0 shl 4);
|
{ set U flag }
|
||||||
bytes:=bytes or ((-oper[1]^.ref^.offset) and $f);
|
bytes:=bytes or (1 shl 23)
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
offset:=-offset;
|
||||||
{ set U bit }
|
bytes:=bytes or (offset and $F);
|
||||||
bytes:=bytes or (1 shl 23);
|
bytes:=bytes or ((offset and $F0) shl 4);
|
||||||
bytes:=bytes or (oper[1]^.ref^.offset and $f0 shl 4);
|
|
||||||
bytes:=bytes or (oper[1]^.ref^.offset and $f);
|
|
||||||
end;
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
@ -375,9 +375,9 @@ reg32,immshifter \xB\x1\xA0 ARM32,ARMv4
|
|||||||
reg32,regf \x10\x01\x0F ARM32,ARMv4
|
reg32,regf \x10\x01\x0F ARM32,ARMv4
|
||||||
|
|
||||||
[MSRcc]
|
[MSRcc]
|
||||||
regf,reg32 \x12\x01\x28\xF0 ARM32,ARMv4
|
regf,reg32 \x12\x01\x20\xF0 ARM32,ARMv4
|
||||||
regf,immshifter \x13\x03\x28\xF0 ARM32,ARMv4
|
regf,immshifter \x13\x03\x20\xF0 ARM32,ARMv4
|
||||||
regs,immshifter \x13\x03\x28\xF0 ARM32,ARMv4
|
regs,immshifter \x13\x03\x20\xF0 ARM32,ARMv4
|
||||||
|
|
||||||
[MULcc]
|
[MULcc]
|
||||||
reglo,reglo \x64\x43\x40 THUMB,ARMv4T
|
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
|
reg32,reg32,reg32,reg32 \x16\x01\x40\xE ARM32,ARMv5TE
|
||||||
|
|
||||||
[SMLAWBcc]
|
[SMLAWBcc]
|
||||||
|
reg32,reg32,reg32,reg32 \x80\xFB\x30\x0\x00 THUMB32,ARMv6T2
|
||||||
|
reg32,reg32,reg32,reg32 \x15\x1\x20\x8 ARM32,ARMv5TE
|
||||||
|
|
||||||
[SMLAWTcc]
|
[SMLAWTcc]
|
||||||
|
reg32,reg32,reg32,reg32 \x80\xFB\x30\x0\x10 THUMB32,ARMv6T2
|
||||||
|
reg32,reg32,reg32,reg32 \x15\x1\x20\xC ARM32,ARMv5TE
|
||||||
|
|
||||||
[VLDMcc]
|
[VLDMcc]
|
||||||
memam4,reglist \x44\xC\x10\xA ARM32,VFPv2
|
memam4,reglist \x44\xC\x10\xA ARM32,VFPv2
|
||||||
@ -1331,9 +1335,11 @@ reglist \x26\x80 ARM32,ARMv4
|
|||||||
|
|
||||||
[SDIVcc]
|
[SDIVcc]
|
||||||
reg32,reg32,reg32 \x80\xFB\x90\xF0\xF0 THUMB32,ARMv7R,ARMv7M
|
reg32,reg32,reg32 \x80\xFB\x90\xF0\xF0 THUMB32,ARMv7R,ARMv7M
|
||||||
|
reg32,reg32,reg32 \x15\x07\x10\x01\xF ARM32,ARMv7
|
||||||
|
|
||||||
[UDIVcc]
|
[UDIVcc]
|
||||||
reg32,reg32,reg32 \x80\xFB\xB0\xF0\xF0 THUMB32,ARMv7R,ARMv7M
|
reg32,reg32,reg32 \x80\xFB\xB0\xF0\xF0 THUMB32,ARMv7R,ARMv7M
|
||||||
|
reg32,reg32,reg32 \x15\x07\x30\x01\xF ARM32,ARMv7
|
||||||
|
|
||||||
[MOVTcc]
|
[MOVTcc]
|
||||||
reg32,imm \x81\xF2\xC0\x0\x0 THUMB32,ARMv6T2
|
reg32,imm \x81\xF2\xC0\x0\x0 THUMB32,ARMv6T2
|
||||||
@ -1501,6 +1507,7 @@ immshifter \x2E\xF5\x7F\xF0\x40 ARM32,ARMv7
|
|||||||
|
|
||||||
[SMC]
|
[SMC]
|
||||||
immshifter \x2E\x01\x60\x00\x70 ARM32,ARMv7
|
immshifter \x2E\x01\x60\x00\x70 ARM32,ARMv7
|
||||||
|
imm32 \x2E\x01\x60\x00\x70 ARM32,ARMv7
|
||||||
|
|
||||||
; Thumb armv6-m (gcc)
|
; Thumb armv6-m (gcc)
|
||||||
[NEG]
|
[NEG]
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
{ don't edit, this file is generated from armins.dat }
|
{ don't edit, this file is generated from armins.dat }
|
||||||
703;
|
710;
|
||||||
|
@ -1187,21 +1187,21 @@
|
|||||||
opcode : A_MSR;
|
opcode : A_MSR;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
optypes : (ot_regf,ot_reg32,ot_none,ot_none,ot_none,ot_none);
|
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
|
flags : if_arm32 or if_armv4
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
opcode : A_MSR;
|
opcode : A_MSR;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
optypes : (ot_regf,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none);
|
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
|
flags : if_arm32 or if_armv4
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
opcode : A_MSR;
|
opcode : A_MSR;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
optypes : (ot_regs,ot_immediateshifter,ot_none,ot_none,ot_none,ot_none);
|
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
|
flags : if_arm32 or if_armv4
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -2310,6 +2310,34 @@
|
|||||||
code : #22#1#64#14;
|
code : #22#1#64#14;
|
||||||
flags : if_arm32 or if_armv5te
|
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;
|
opcode : A_VLDM;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
@ -4354,6 +4382,13 @@
|
|||||||
code : #128#251#144#240#240;
|
code : #128#251#144#240#240;
|
||||||
flags : if_thumb32 or if_armv7r or if_armv7m
|
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;
|
opcode : A_UDIV;
|
||||||
ops : 3;
|
ops : 3;
|
||||||
@ -4361,6 +4396,13 @@
|
|||||||
code : #128#251#176#240#240;
|
code : #128#251#176#240#240;
|
||||||
flags : if_thumb32 or if_armv7r or if_armv7m
|
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;
|
opcode : A_MOVT;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
@ -4872,6 +4914,13 @@
|
|||||||
code : #46#1#96#0#112;
|
code : #46#1#96#0#112;
|
||||||
flags : if_arm32 or if_armv7
|
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;
|
opcode : A_SVC;
|
||||||
ops : 1;
|
ops : 1;
|
||||||
|
@ -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,
|
((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_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_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_MRC,A_MCR,A_MCRR,A_MRRC,A_MRC2,A_MCR2,A_MCRR2,A_MRRC2,
|
||||||
A_STREXD,A_STRD,
|
A_STREXD,A_STRD,
|
||||||
A_USADA8,
|
A_USADA8,
|
||||||
|
Loading…
Reference in New Issue
Block a user