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:
Jeppe Johansen 2015-01-02 13:24:03 +00:00
parent 7390acc426
commit 572076fc4d
4 changed files with 89 additions and 3 deletions

View File

@ -3327,6 +3327,22 @@ implementation
{ set Rn }
bytes:=bytes or (getsupreg(oper[0]^.reg) shl 16);
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 }
bytes:=bytes or MakeRegList(oper[1]^.regset^);
end
@ -5083,6 +5099,59 @@ implementation
(oper[0]^.typ=top_const) then
bytes:=bytes or (oper[0]^.val and $1F);
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) }
begin
{ set instruction code }
@ -5127,7 +5196,7 @@ implementation
bytes:=bytes or getsupreg(oper[2]^.ref^.base) shl 16;
bytes:=bytes or ((oper[2]^.ref^.offset shr 2) and $FF);
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
bytes:=bytes or (1 shl 21);
@ -5274,7 +5343,7 @@ implementation
end;
{ 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);
{ we're finished, write code }

View File

@ -395,9 +395,12 @@ reg32,reg32,shifterop \xA\x1\xA0 ARM32,ARMv4
reg32,immshifter \xB\x1\xA0 ARM32,ARMv4
[MRScc]
reg32,regf \x90\xF3\xEF\x80\x0 THUMB32,ARMv6
reg32,regf \x10\x01\x0F ARM32,ARMv4
[MSRcc]
regf,reg32 \x90\xF3\x80\x80\x0 THUMB32,ARMv6
regf,reg32 \x12\x01\x20\xF0 ARM32,ARMv4
regf,immshifter \x13\x03\x20\xF0 ARM32,ARMv4
regs,immshifter \x13\x03\x20\xF0 ARM32,ARMv4

View File

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

View File

@ -1323,6 +1323,13 @@
code : #11#1#160;
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;
ops : 2;
@ -1330,6 +1337,13 @@
code : #16#1#15;
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;
ops : 2;