diff options
| author | Mary <me@thog.eu> | 2021-08-27 00:07:44 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-27 00:07:44 +0200 |
| commit | 501c3d5cea6b96f991453cc6f8d395d358d0d4c3 (patch) | |
| tree | bb6ba8c0ec94fef280752296e6532c7cfedc9863 /ARMeilleure/Decoders | |
| parent | 8e1adb95cf7f67b976f105f4cac26d3ff2986057 (diff) | |
Implement MSR instruction for A32 (#2585)
* Implement MSR instruction
Fix #1342.
Now Pocket Rumble is playable.
* Address gdkchan's comments
* Address gdkchan's comments
* Address gdkchan's comment
Diffstat (limited to 'ARMeilleure/Decoders')
| -rw-r--r-- | ARMeilleure/Decoders/OpCode32MsrReg.cs | 29 | ||||
| -rw-r--r-- | ARMeilleure/Decoders/OpCodeTable.cs | 1 |
2 files changed, 30 insertions, 0 deletions
diff --git a/ARMeilleure/Decoders/OpCode32MsrReg.cs b/ARMeilleure/Decoders/OpCode32MsrReg.cs new file mode 100644 index 00000000..d897ffd8 --- /dev/null +++ b/ARMeilleure/Decoders/OpCode32MsrReg.cs @@ -0,0 +1,29 @@ +using ARMeilleure.State; + +namespace ARMeilleure.Decoders +{ + class OpCode32MsrReg : OpCode32 + { + public bool R { get; } + public int Mask { get; } + public int Rd { get; } + public bool Banked { get; } + public int Rn { get; } + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32MsrReg(inst, address, opCode); + + public OpCode32MsrReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + R = ((opCode >> 22) & 1) != 0; + Mask = (opCode >> 16) & 0xf; + Rd = (opCode >> 12) & 0xf; + Banked = ((opCode >> 9) & 1) != 0; + Rn = (opCode >> 0) & 0xf; + + if (Rn == RegisterAlias.Aarch32Pc || Mask == 0) + { + Instruction = InstDescriptor.Undefined; + } + } + } +} diff --git a/ARMeilleure/Decoders/OpCodeTable.cs b/ARMeilleure/Decoders/OpCodeTable.cs index c1ac8363..12ff051c 100644 --- a/ARMeilleure/Decoders/OpCodeTable.cs +++ b/ARMeilleure/Decoders/OpCodeTable.cs @@ -702,6 +702,7 @@ namespace ARMeilleure.Decoders SetA32("<<<<00110100xxxxxxxxxxxxxxxxxxxx", InstName.Movt, InstEmit32.Movt, OpCode32AluImm16.Create); SetA32("<<<<1110xxx1xxxxxxxx111xxxx1xxxx", InstName.Mrc, InstEmit32.Mrc, OpCode32System.Create); SetA32("<<<<11000101xxxxxxxx111xxxxxxxxx", InstName.Mrrc, InstEmit32.Mrrc, OpCode32System.Create); + SetA32("<<<<00010x10xxxx111100000000xxxx", InstName.Msr, InstEmit32.Msr, OpCode32MsrReg.Create); SetA32("<<<<0000000xxxxx0000xxxx1001xxxx", InstName.Mul, InstEmit32.Mul, OpCode32AluMla.Create); SetA32("<<<<0011111x0000xxxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCode32AluImm.Create); SetA32("<<<<0001111x0000xxxxxxxxxxx0xxxx", InstName.Mvn, InstEmit32.Mvn, OpCode32AluRsImm.Create); |
