mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 13:39:36 +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;
|
||||
{ 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
|
||||
|
@ -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]
|
||||
|
@ -1,2 +1,2 @@
|
||||
{ don't edit, this file is generated from armins.dat }
|
||||
703;
|
||||
710;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user