mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 22:09:28 +02:00
Add MSR/MRS for ARMv6M/7M.
Fix bug in FPA LFM/SFM. Add usermode handling of LDM/STM. git-svn-id: branches/laksen/armiw@29371 -
This commit is contained in:
parent
7390acc426
commit
572076fc4d
@ -3327,6 +3327,22 @@ implementation
|
|||||||
{ set Rn }
|
{ set Rn }
|
||||||
bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16);
|
bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if oper[1]^.usermode then
|
||||||
|
begin
|
||||||
|
if (oper[0]^.typ=top_ref) then
|
||||||
|
begin
|
||||||
|
if (opcode=A_LDM) and
|
||||||
|
(RS_PC in oper[1]^.regset^) then
|
||||||
|
begin
|
||||||
|
// Valid exception return
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Message(asmw_e_invalid_opcode_and_operands);
|
||||||
|
end;
|
||||||
|
|
||||||
|
bytes:=bytes or (1 shl 22);
|
||||||
|
end;
|
||||||
{ reglist }
|
{ reglist }
|
||||||
bytes:=bytes or MakeRegList(oper[1]^.regset^);
|
bytes:=bytes or MakeRegList(oper[1]^.regset^);
|
||||||
end
|
end
|
||||||
@ -5083,6 +5099,59 @@ implementation
|
|||||||
(oper[0]^.typ=top_const) then
|
(oper[0]^.typ=top_const) then
|
||||||
bytes:=bytes or (oper[0]^.val and $1F);
|
bytes:=bytes or (oper[0]^.val and $1F);
|
||||||
end;
|
end;
|
||||||
|
#$96: { Thumb-2: MSR/MRS }
|
||||||
|
begin
|
||||||
|
{ set instruction code }
|
||||||
|
bytes:=bytes or (ord(insentry^.code[1]) shl 24);
|
||||||
|
bytes:=bytes or (ord(insentry^.code[2]) shl 16);
|
||||||
|
bytes:=bytes or (ord(insentry^.code[3]) shl 8);
|
||||||
|
bytes:=bytes or ord(insentry^.code[4]);
|
||||||
|
|
||||||
|
if opcode=A_MRS then
|
||||||
|
begin
|
||||||
|
bytes:=bytes or (getsupreg(oper[0]^.reg) shl 8);
|
||||||
|
|
||||||
|
case oper[1]^.reg of
|
||||||
|
NR_MSP: bytes:=bytes or $08;
|
||||||
|
NR_PSP: bytes:=bytes or $09;
|
||||||
|
|
||||||
|
NR_IPSR: bytes:=bytes or $05;
|
||||||
|
NR_EPSR: bytes:=bytes or $06;
|
||||||
|
NR_APSR: bytes:=bytes or $00;
|
||||||
|
|
||||||
|
NR_PRIMASK: bytes:=bytes or $10;
|
||||||
|
NR_BASEPRI: bytes:=bytes or $11;
|
||||||
|
NR_BASEPRI_MAX: bytes:=bytes or $12;
|
||||||
|
NR_FAULTMASK: bytes:=bytes or $13;
|
||||||
|
NR_CONTROL: bytes:=bytes or $14;
|
||||||
|
else
|
||||||
|
Message(asmw_e_invalid_opcode_and_operands);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
bytes:=bytes or (getsupreg(oper[1]^.reg) shl 16);
|
||||||
|
|
||||||
|
case oper[0]^.reg of
|
||||||
|
NR_APSR,
|
||||||
|
NR_APSR_nzcvqg: bytes:=bytes or $C00;
|
||||||
|
NR_APSR_g: bytes:=bytes or $400;
|
||||||
|
NR_APSR_nzcvq: bytes:=bytes or $800;
|
||||||
|
|
||||||
|
NR_MSP: bytes:=bytes or $08;
|
||||||
|
NR_PSP: bytes:=bytes or $09;
|
||||||
|
|
||||||
|
NR_PRIMASK: bytes:=bytes or $10;
|
||||||
|
NR_BASEPRI: bytes:=bytes or $11;
|
||||||
|
NR_BASEPRI_MAX: bytes:=bytes or $12;
|
||||||
|
|
||||||
|
NR_FAULTMASK: bytes:=bytes or $13;
|
||||||
|
NR_CONTROL: bytes:=bytes or $14;
|
||||||
|
else
|
||||||
|
Message(asmw_e_invalid_opcode_and_operands);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
#$A0: { FPA: CPDT(LDF/STF) }
|
#$A0: { FPA: CPDT(LDF/STF) }
|
||||||
begin
|
begin
|
||||||
{ set instruction code }
|
{ set instruction code }
|
||||||
@ -5127,7 +5196,7 @@ implementation
|
|||||||
bytes:=bytes or getsupreg(oper[2]^.ref^.base) shl 16;
|
bytes:=bytes or getsupreg(oper[2]^.ref^.base) shl 16;
|
||||||
bytes:=bytes or ((oper[2]^.ref^.offset shr 2) and $FF);
|
bytes:=bytes or ((oper[2]^.ref^.offset shr 2) and $FF);
|
||||||
if oper[2]^.ref^.offset>=0 then
|
if oper[2]^.ref^.offset>=0 then
|
||||||
bytes:=bytes or (2 shl 23);
|
bytes:=bytes or (1 shl 23);
|
||||||
|
|
||||||
if oper[2]^.ref^.addressmode<>AM_OFFSET then
|
if oper[2]^.ref^.addressmode<>AM_OFFSET then
|
||||||
bytes:=bytes or (1 shl 21);
|
bytes:=bytes or (1 shl 21);
|
||||||
@ -5274,7 +5343,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{ Todo: Decide whether the code above should take care of writing data in an order that makes senes }
|
{ Todo: Decide whether the code above should take care of writing data in an order that makes senes }
|
||||||
if (insentry^.code[0] in [#$80..#$95]) and (bytelen=4) then
|
if (insentry^.code[0] in [#$80..#$96]) and (bytelen=4) then
|
||||||
bytes:=((bytes shr 16) and $FFFF) or ((bytes and $FFFF) shl 16);
|
bytes:=((bytes shr 16) and $FFFF) or ((bytes and $FFFF) shl 16);
|
||||||
|
|
||||||
{ we're finished, write code }
|
{ we're finished, write code }
|
||||||
|
@ -395,9 +395,12 @@ reg32,reg32,shifterop \xA\x1\xA0 ARM32,ARMv4
|
|||||||
reg32,immshifter \xB\x1\xA0 ARM32,ARMv4
|
reg32,immshifter \xB\x1\xA0 ARM32,ARMv4
|
||||||
|
|
||||||
[MRScc]
|
[MRScc]
|
||||||
|
reg32,regf \x90\xF3\xEF\x80\x0 THUMB32,ARMv6
|
||||||
reg32,regf \x10\x01\x0F ARM32,ARMv4
|
reg32,regf \x10\x01\x0F ARM32,ARMv4
|
||||||
|
|
||||||
[MSRcc]
|
[MSRcc]
|
||||||
|
regf,reg32 \x90\xF3\x80\x80\x0 THUMB32,ARMv6
|
||||||
|
|
||||||
regf,reg32 \x12\x01\x20\xF0 ARM32,ARMv4
|
regf,reg32 \x12\x01\x20\xF0 ARM32,ARMv4
|
||||||
regf,immshifter \x13\x03\x20\xF0 ARM32,ARMv4
|
regf,immshifter \x13\x03\x20\xF0 ARM32,ARMv4
|
||||||
regs,immshifter \x13\x03\x20\xF0 ARM32,ARMv4
|
regs,immshifter \x13\x03\x20\xF0 ARM32,ARMv4
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
{ don't edit, this file is generated from armins.dat }
|
{ don't edit, this file is generated from armins.dat }
|
||||||
826;
|
828;
|
||||||
|
@ -1323,6 +1323,13 @@
|
|||||||
code : #11#1#160;
|
code : #11#1#160;
|
||||||
flags : if_arm32 or if_armv4
|
flags : if_arm32 or if_armv4
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
opcode : A_MRS;
|
||||||
|
ops : 2;
|
||||||
|
optypes : (ot_reg32,ot_regf,ot_none,ot_none,ot_none,ot_none);
|
||||||
|
code : #144#243#239#128#0;
|
||||||
|
flags : if_thumb32 or if_armv6
|
||||||
|
),
|
||||||
(
|
(
|
||||||
opcode : A_MRS;
|
opcode : A_MRS;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
@ -1330,6 +1337,13 @@
|
|||||||
code : #16#1#15;
|
code : #16#1#15;
|
||||||
flags : if_arm32 or if_armv4
|
flags : if_arm32 or if_armv4
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
opcode : A_MSR;
|
||||||
|
ops : 2;
|
||||||
|
optypes : (ot_regf,ot_reg32,ot_none,ot_none,ot_none,ot_none);
|
||||||
|
code : #144#243#128#128#0;
|
||||||
|
flags : if_thumb32 or if_armv6
|
||||||
|
),
|
||||||
(
|
(
|
||||||
opcode : A_MSR;
|
opcode : A_MSR;
|
||||||
ops : 2;
|
ops : 2;
|
||||||
|
Loading…
Reference in New Issue
Block a user