[ARM] add handful of floating point instructions and most importantly: NOP!
This commit is contained in:
parent
510e52271b
commit
e78708213c
|
@ -163,10 +163,10 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
}
|
||||
else opcode = opcode.Replace(crepl, "");
|
||||
|
||||
if(opcode.Contains("{.size}"))
|
||||
{
|
||||
opcode = opcode.Replace("<{.size}>","." + args[argindex++].ToString());
|
||||
}
|
||||
if(opcode.Contains("{.fpsize}"))
|
||||
opcode = opcode.Replace("<{.fpsize}>",".F" + args[argindex++].ToString());
|
||||
if (opcode.Contains(".fpsize"))
|
||||
opcode = opcode.Replace("<.fpsize>", ".F" + args[argindex++].ToString());
|
||||
//---------
|
||||
|
||||
string cpcomment = null;
|
||||
|
@ -215,6 +215,26 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
break;
|
||||
}
|
||||
|
||||
case "sdd":
|
||||
case "sdn":
|
||||
case "sdm":
|
||||
if ((bool)args[argindex++])
|
||||
item = "s" + args[argindex++].ToString();
|
||||
else
|
||||
item = "d" + args[argindex++].ToString();
|
||||
break;
|
||||
|
||||
case "{sdd~sdn, }":
|
||||
{
|
||||
bool s = (bool)args[argindex++];
|
||||
uint rd = (uint)args[argindex++];
|
||||
uint rx = (uint)args[argindex++];
|
||||
if (disopt.showExplicitAccumulateRegisters || rd != rx)
|
||||
item = string.Format("{0}{1}, ", s ? "s" : "d", rd);
|
||||
else item = "";
|
||||
break;
|
||||
}
|
||||
|
||||
case "fpscr": item = nstyle ? "fpscr" : "FPSCR"; break;
|
||||
|
||||
case "const": item = string.Format("0x{0:x}", args[argindex++]); break;
|
||||
|
@ -228,7 +248,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
else item = string.Format(",#0x{0:x}", temp);
|
||||
break;
|
||||
}
|
||||
case "{,+/-#imm}":
|
||||
case "{, #+/-imm}":
|
||||
{
|
||||
uint temp = (uint)args[argindex + 1];
|
||||
if (temp == 0 && disopt.hideZeroOffset) item = "";
|
||||
|
|
|
@ -112,7 +112,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
opcode += "<c>";
|
||||
//we may want conditional logic here to control whether various registers are displayed (we used to have it, but i changed my mind)
|
||||
if (offset)
|
||||
return DISNEW(opcode, rt + ", [<Rn!><{,+/-#imm}>]", t, n, add, imm32);
|
||||
return DISNEW(opcode, rt + ", [<Rn!><{, #+/-imm}>]", t, n, add, imm32);
|
||||
else if (preindexed)
|
||||
return DISNEW(opcode, rt + ", [<Rn!>, <+/-><imm>]!", t, n, add, imm32);
|
||||
else if (postindex)
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
.r("A==0 && op1 == #0x010", () => Execute_Unhandled("STRT on page A8-416"))
|
||||
.r("A==1 && op1 == #0x010 && B==0", () => Execute_Unhandled("STRT on page A8-416"))
|
||||
.r("A==0 && op1 == #xx0x1 && op1 != #0x011 && Rn != #1111", () => Execute_LDR_immediate_arm_A1())
|
||||
.r("A==0 && op1 == #xx0x1 && op1 != #0x011 && Rn == #1111", () => ExecuteArm_LDR_literal_A1())
|
||||
.r("A==0 && op1 == #xx0x1 && op1 != #0x011 && Rn == #1111", () => Execute_LDR_literal_A1())
|
||||
.r("A==1 && op1 == #xx0x1 && A != #0x011 && B==0", () => Execute_Unhandled("LDR (register) on page A8-124"))
|
||||
.r("A==0 && op1 == #0x011", () => Execute_Unhandled("LDRT on page A8-176"))
|
||||
.r("A==1 && op1 == #0x011 && B==0", () => Execute_Unhandled("LDRT on page A8-176"))
|
||||
|
@ -141,7 +141,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return ExecuteCore_PUSH(Encoding.A2, registers, UnalignedAllowed);
|
||||
}
|
||||
|
||||
uint ExecuteArm_LDR_literal_A1()
|
||||
uint Execute_LDR_literal_A1()
|
||||
{
|
||||
//A8.6.59
|
||||
//A8-122
|
||||
|
@ -182,7 +182,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return ExecuteArm_DataProcessing_Immediate();
|
||||
if (op1 == _.b10000) return Execute_Unhandled("16-bit immediate load (MOV (immediate on page A8-193) //v6T2");
|
||||
if (op1 == _.b10100) return Execute_Unhandled("high halfword 16-bit immediate load (MOVT on page A8-200) //v6T2");
|
||||
if (CHK(op1, _.b11011, _.b10010)) return Execute_Unhandled("MSR (immediate), and hints on page A5-17");
|
||||
if (CHK(op1, _.b11011, _.b10010)) return ExecuteArm_MSR_immediate_and_hints();
|
||||
throw new InvalidOperationException("unexpected decoder fail");
|
||||
|
||||
default:
|
||||
|
@ -190,6 +190,48 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
}
|
||||
}
|
||||
|
||||
uint ExecuteArm_MSR_immediate_and_hints()
|
||||
{
|
||||
Bit op = _.BIT22(instruction);
|
||||
uint op1 = (instruction >> 16) & 0xF;
|
||||
uint op2 = instruction & 0xFF;
|
||||
if (op == 0)
|
||||
{
|
||||
switch(op1)
|
||||
{
|
||||
case _.b0000:
|
||||
switch (op2)
|
||||
{
|
||||
case 0: return Execute_NOP_A1();
|
||||
case 1: return Execute_Unhandled("yield");
|
||||
case 2: return Execute_Unhandled("wfe");
|
||||
case 3: return Execute_Unhandled("wfi");
|
||||
case 4: return Execute_Unhandled("sev");
|
||||
default: return Execute_Unhandled("DBG");
|
||||
}
|
||||
case _.b0100:
|
||||
case _.b1000: case _.b1100:
|
||||
return Execute_Unhandled("MSR immediate");
|
||||
case _.b0001: case _.b0101:
|
||||
case _.b1001: case _.b1101:
|
||||
return Execute_Unhandled("MSR immediate");
|
||||
case _.b0010: case _.b0011:
|
||||
case _.b0110: case _.b0111:
|
||||
case _.b1010: case _.b1011:
|
||||
case _.b1110: case _.b1111:
|
||||
return Execute_Unhandled("MSR immediate");
|
||||
default: throw new InvalidOperationException("decode fail");
|
||||
}
|
||||
}
|
||||
else return Execute_Unhandled("MSR immediate");
|
||||
}
|
||||
|
||||
uint Execute_NOP_A1()
|
||||
{
|
||||
//A8.6.110
|
||||
return ExecuteCore_NOP(Encoding.A1);
|
||||
}
|
||||
|
||||
uint ExecuteArm_SynchronizationPrimitives()
|
||||
{
|
||||
uint op = (instruction >> 20) & 0xF;
|
||||
|
@ -562,7 +604,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
case _.b001:
|
||||
switch (op)
|
||||
{
|
||||
case _.b01: return ExecuteArm_BX_A1();
|
||||
case _.b01: return Execute_BX_A1();
|
||||
case _.b11: return Execute_Unhandled("ExecuteArm_CLZ");
|
||||
default:
|
||||
return Execute_Undefined();
|
||||
|
@ -588,16 +630,11 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
} //switch(op2)
|
||||
}
|
||||
|
||||
uint ExecuteArm_BX_A1()
|
||||
uint Execute_BX_A1()
|
||||
{
|
||||
//A8-62
|
||||
//A8.6.25
|
||||
uint Rm = Reg16(0);
|
||||
if (disassemble)
|
||||
return DIS("BX/c/", "/r0/", Rm);
|
||||
uint m = r[Rm];
|
||||
_BXWritePC(m);
|
||||
return 1;
|
||||
uint m = Reg16(0);
|
||||
return ExecuteCore_BX(Encoding.A1, m);
|
||||
}
|
||||
|
||||
uint ExecuteArm_Media() { return Execute_Unhandled("ExecuteArm_Media"); }
|
||||
|
@ -720,7 +757,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
.r("op1==#00010x && coproc_special==#1", () => Execute_Unhandled("ExecuteArm_SIMD_VFP_64bit_xfer"))
|
||||
.r("op1==#000100 && coproc_special==#0", () => Execute_Unhandled("MCRR,MCRR2"))
|
||||
.r("op1==#000101 && coproc_special==#0", () => Execute_Unhandled("MRRC,MRRC2"))
|
||||
.r("op1==#10xxxx && op==0 && coproc_special==#1", () => Execute_Unhandled("VFP data-processing on page A7-24"))
|
||||
.r("op1==#10xxxx && op==0 && coproc_special==#1", () => ExecuteArm_VFP_DataProcessing())
|
||||
.r("op1==#10xxxx && op==0 && coproc_special==#0", () => Execute_Unhandled("CDP,CDP2 on page A8-68"))
|
||||
.r("op1==#10xxxx && op==1 && coproc_special==#1", () => ExecuteArm_ShortVFPTransfer())
|
||||
.r("op1==#10xxx0 && op==1 && coproc_special==#0", () => Execute_Unhandled("MCR,MCR2 on pageA8-186"))
|
||||
|
@ -739,6 +776,124 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return 1;
|
||||
}
|
||||
|
||||
uint ExecuteArm_VFP_DataProcessing()
|
||||
{
|
||||
//A7.5
|
||||
uint opc1 = (instruction >> 20) & 0xF;
|
||||
uint opc2 = (instruction >> 16) & 0xF;
|
||||
uint opc3 = (instruction >> 6) & 3;
|
||||
|
||||
if (opc1 == _.b0000 || opc1 == _.b0100) return Execute_Unhandled("VML, VMLS (floating point)");
|
||||
if (opc1 == _.b0001 || opc1 == _.b0101) return Execute_Unhandled("VNMLA, VNMLS, VNMUL");
|
||||
if (opc1 == _.b0010 || opc1 == _.b0110)
|
||||
if (opc3 == _.b01 || opc3 == _.b11) return Execute_Unhandled("VMUL (floating point)");
|
||||
else if (opc3 == _.b00 || opc3 == _.b10) return Execute_Unhandled("VMUL (floating point)");
|
||||
else throw new InvalidOperationException("decode fail");
|
||||
if (opc1 == _.b0011 || opc1 == _.b0111)
|
||||
if (opc3 == _.b00 || opc3 == _.b10) return Execute_VADD_floating_point_A2();
|
||||
else if (opc3 == _.b01 || opc3 == _.b11) return Execute_Unhandled("VSUB (floating point)");
|
||||
if (opc1 == _.b1000 || opc1 == _.b1100)
|
||||
if (opc3 == _.b00 || opc3 == _.b10) return Execute_Unhandled("VDIV");
|
||||
else throw new InvalidOperationException("unhandled opcode space..");
|
||||
if (opc1 == _.b1011 || opc1 == _.b1111)
|
||||
{
|
||||
if (opc3 == _.b00 || opc3 == _.b10) return Execute_Unhandled("VMOV (immediate)");
|
||||
if (opc2 == _.b0000 && opc3 == _.b01) return Execute_VMOV_register_A2();
|
||||
if (opc2 == _.b0000 && opc3 == _.b11) return Execute_Unhandled("VABS");
|
||||
if (opc2 == _.b0001 && opc3 == _.b01) return Execute_Unhandled("VNEG");
|
||||
if (opc2 == _.b0001 && opc3 == _.b11) return Execute_Unhandled("VSQRT");
|
||||
if (opc2 == _.b0010 || opc2 == _.b0011) return Execute_Unhandled("VCVTB, VCVTT (between half-precision and single precision)");
|
||||
if (opc2 == _.b0100 || opc2 == _.b0101) return Execute_Unhandled("VCMP, VCMPE");
|
||||
if (opc2 == _.b0111) return Execute_Unhandled("VCVT (between double precision and single precision)");
|
||||
if (opc2 == _.b1000) return Execute_Unhandled("VCVT, VCVTR (between floating point and integer)");
|
||||
if (opc2 == _.b1010 || opc2 == _.b1011) return Execute_Unhandled("VCVT (between floating point and fixed point)");
|
||||
if (opc2 == _.b1100 || opc2 == _.b1101) return Execute_Unhandled("VCVT, VCVTR (between floating point and integer)");
|
||||
if (opc2 == _.b1110 || opc2 == _.b1111) return Execute_Unhandled("VCVT (between floating point and fixed point)");
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("decoder fail");
|
||||
}
|
||||
|
||||
uint Execute_VADD_floating_point_A2()
|
||||
{
|
||||
//A8.6.272
|
||||
if (_FPSCR_LEN() != _.b000 || _FPSCR_STRIDE() != _.b00) throw new NotImplementedException("see VFP vectors");
|
||||
const bool advsimd = false;
|
||||
Bit sz = _.BIT8(instruction);
|
||||
bool dp_operation = (sz == 1);
|
||||
uint D = _.BIT22(instruction);
|
||||
uint M = _.BIT5(instruction);
|
||||
uint N = _.BIT7(instruction);
|
||||
uint Vm = Reg16(0);
|
||||
uint Vd = Reg16(12);
|
||||
uint Vn = Reg16(16);
|
||||
uint d = dp_operation ? ((D << 4) | Vd) : ((Vd << 1) | D);
|
||||
uint n = dp_operation ? ((N << 4) | Vn) : ((Vn << 1) | N);
|
||||
uint m = dp_operation ? ((M << 4) | Vm) : ((Vm << 1) | M);
|
||||
return ExecuteCore_VADD_floating_point(Encoding.A2, dp_operation, advsimd, d, n, m);
|
||||
}
|
||||
|
||||
uint Execute_VMOV_register_A2()
|
||||
{
|
||||
//A8.6.327
|
||||
if (_FPSCR_LEN() != _.b000 || _FPSCR_STRIDE() != _.b00) throw new NotImplementedException("see VFP vectors");
|
||||
Bit sz = _.BIT8(instruction);
|
||||
bool single_register = (sz == 0);
|
||||
const bool advsimd = false;
|
||||
uint d,m;
|
||||
uint Vd = Reg16(12);
|
||||
uint Vm = Reg16(0);
|
||||
uint D = _.BIT22(instruction);
|
||||
uint M = _.BIT5(instruction);
|
||||
uint regs = 0;
|
||||
if (single_register)
|
||||
{
|
||||
d = (Vd << 1) | D;
|
||||
m = (Vm << 1) | M;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
d = (D << 4) | Vd;
|
||||
m = (M << 4) | Vm;
|
||||
regs = 1;
|
||||
}
|
||||
|
||||
return ExecuteCore_VMOV_register(Encoding.A2, single_register, advsimd, d, m, regs);
|
||||
}
|
||||
|
||||
uint Execute_VMOV_immediate_A2()
|
||||
{
|
||||
////A8.6.326
|
||||
//if (_FPSCR_LEN() != _.b000 || _FPSCR_STRIDE() != _.b00) throw new NotImplementedException("see VFP vectors");
|
||||
//Bit sz = _.BIT8(instruction);
|
||||
//bool single_register = (sz == 0);
|
||||
//const bool advsimd = false;
|
||||
//uint d;
|
||||
//uint Vd = Reg16(12);
|
||||
//uint D = _.BIT22(instruction);
|
||||
//uint imm32 = 0;
|
||||
//ulong imm64 = 0;
|
||||
//uint imm4H = (instruction>>16)&0xF;
|
||||
//uint imm4L = (instruction&0xF);
|
||||
//uint regs = 0;
|
||||
//if (single_register)
|
||||
//{
|
||||
// d = (Vd << 1) | D;
|
||||
// imm32 = _VFPExpandImm32((imm4H << 4) | imm4L);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// d = (D << 4) | Vd;
|
||||
// imm64 = _VFPExpandImm64((imm4H << 4) | imm4L);
|
||||
// regs = 1;
|
||||
//}
|
||||
|
||||
//return ExecuteCore_VMOV(Encoding.A2, single_register, advsimd, d, regs, imm32, imm64);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint Execute_ExtensionRegister_LoadStore()
|
||||
{
|
||||
//A7.6 Extension register load/store instructions
|
||||
|
@ -781,7 +936,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
uint imm8 = instruction & 0xFF;
|
||||
uint imm32 = _ZeroExtend_32(imm8 << 2);
|
||||
uint Vd = Reg16(12);
|
||||
uint n = Reg16(0);
|
||||
uint n = Reg16(16);
|
||||
uint d = (Vd << 1) | D;
|
||||
return ExecuteCore_VLDR(Encoding.A1, single_reg, add, d, n, imm32);
|
||||
}
|
||||
|
@ -837,7 +992,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
Decoder_ExecuteArm_ShortVFPTransfer.Ensure(() => Decoder_ExecuteArm_ShortVFPTransfer
|
||||
.d("A", 3).d("L", 1).d("C", 1).d("B", 2)
|
||||
.r("L==0 && C==0 && A==#000", () => Execute_Unhandled("VMOV (between ARM core register and single-precision register) on page A8-648"))
|
||||
.r("L==0 && C==0 && A==#111", () => ExecuteArm_VMSR_A1())
|
||||
.r("L==0 && C==0 && A==#111", () => Execute_VMSR_A1())
|
||||
.r("L==0 && C==1 && A==#0xx", () => Execute_Unhandled("VMOV (ARM core register to scalar) on page A8-644"))
|
||||
.r("L==0 && C==1 && A==#1xx && B==#0x", () => Execute_Unhandled("VDUP (ARM core register) on page A8-594"))
|
||||
.r("L==1 && C==0 && A==#000", () => Execute_Unhandled("VMOV (between ARM core register and single-precision register) on page A8-648"))
|
||||
|
@ -854,7 +1009,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return 1;
|
||||
}
|
||||
|
||||
uint ExecuteArm_VMSR_A1()
|
||||
uint Execute_VMSR_A1()
|
||||
{
|
||||
uint t = Reg16(12);
|
||||
if (t == 15 || (t == 13 && _CurrentInstrSet() != EInstrSet.ARM)) return _UNPREDICTABLE();
|
||||
|
|
|
@ -211,6 +211,17 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return 1;
|
||||
}
|
||||
|
||||
//A8.6.25 BX
|
||||
uint ExecuteCore_BX(Encoding encoding, uint m)
|
||||
{
|
||||
if (disassemble)
|
||||
return DISNEW("BX<c>", "<rm>", m);
|
||||
|
||||
_BXWritePC(r[m]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//A8.6.35 CMP (immediate)
|
||||
uint ExecuteCore_CMP_immediate(Encoding encoding, uint n, uint imm32)
|
||||
{
|
||||
|
@ -588,6 +599,14 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return 0;
|
||||
}
|
||||
|
||||
//A8.6.110 NOP
|
||||
uint ExecuteCore_NOP(Encoding encoding)
|
||||
{
|
||||
if (disassemble)
|
||||
return DISNEW("NOP<c>", "");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//A8.6.113 ORR (immediate)
|
||||
uint ExecuteCore_ORR_immediate(Encoding encoding, uint n, uint d, bool setflags, uint imm32, Bit carry)
|
||||
{
|
||||
|
@ -1007,10 +1026,73 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return 1;
|
||||
}
|
||||
|
||||
//A8.6.272 VADD (floating point)
|
||||
uint ExecuteCore_VADD_floating_point(Encoding encoding, bool dp_operation, bool advsimd, uint d, uint n, uint m)
|
||||
{
|
||||
if (advsimd) throw new NotImplementedException("VMOV reg adv simd :(");
|
||||
|
||||
if (disassemble)
|
||||
return DISNEW("VADD<c><.fpsize>", "<{SDd~SDn, }><SDn>, <SDm>", dp_operation ? 64 : 32, !dp_operation, d, n, !dp_operation, n, !dp_operation, m);
|
||||
|
||||
if (advsimd)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dp_operation)
|
||||
D[d] = _FPAdd(D[n], D[m], true);
|
||||
else
|
||||
S[d] = _FPAdd(S[n], S[m], true);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//A8.6.320 VLDR
|
||||
uint ExecuteCore_VLDR(Encoding encoding, bool single_reg, bool add, uint d, uint n, uint imm32)
|
||||
{
|
||||
throw new NotImplementedException("TODO");
|
||||
if (disassemble)
|
||||
return DISNEW("VLDR<c>", "<SDd>, [<rn!><{, #+/-imm}>]", single_reg, d, n, add, imm32);
|
||||
|
||||
_CheckVFPEnabled(true);
|
||||
_NullCheckIfThumbEE(n);
|
||||
uint @base = (n==15)?_Align(PC,4):r[n];
|
||||
uint address = add ? (@base + imm32) : (@base - imm32);
|
||||
if (single_reg)
|
||||
S[d] = MemA_ReadSingle(address);
|
||||
else
|
||||
D[d] = MemA_ReadDouble(address);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//A8.6.326 VMOV (immediate)
|
||||
uint ExecuteCore_VMOV_immediate(Encoding encoding, bool single_register, bool advsimd, uint d, uint regs, float imm32, double imm64)
|
||||
{
|
||||
if (advsimd) throw new NotImplementedException("VMOV imm adv simd :(");
|
||||
throw new NotImplementedException("ExecuteCore_VMOV_immediate");
|
||||
|
||||
//if(disassemble)
|
||||
// return DISNEW("VMOV<c><.fpsize>", "<SDd>", single_register?32:64, single_register, d
|
||||
return 1;
|
||||
}
|
||||
|
||||
//A8.6.327 VMOV (register)
|
||||
uint ExecuteCore_VMOV_register(Encoding encoding, bool single_register, bool advsimd, uint d, uint m, uint regs)
|
||||
{
|
||||
if (advsimd) throw new NotImplementedException("VMOV reg adv simd :(");
|
||||
|
||||
if (disassemble)
|
||||
return DISNEW("VMOV<c><.fpsize>", "<SDd>, <SDm>", single_register ? 32 : 64, single_register, d, single_register, m);
|
||||
|
||||
_CheckAdvSIMDOrVFPEnabled(true, advsimd);
|
||||
|
||||
if (single_register)
|
||||
S[d] = S[m];
|
||||
else for (uint r = 0; r <= regs - 1; r++)
|
||||
D[d + r] = D[m + r];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//A8.6.336 VMSR
|
||||
|
@ -1027,7 +1109,7 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
uint ExecuteCore_VPUSH(Encoding encoding, bool single_regs, uint d, uint regs, uint imm32)
|
||||
{
|
||||
if (disassemble)
|
||||
return DISNEW("VPUSH<c><{.size}>", "<list>", single_regs ? 32 : 64, single_regs, d, regs);
|
||||
return DISNEW("VPUSH<c><{.fpsize}>", "<list>", single_regs ? 32 : 64, single_regs, d, regs);
|
||||
|
||||
_CheckVFPEnabled(true);
|
||||
_NullCheckIfThumbEE(13);
|
||||
|
|
|
@ -89,6 +89,13 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return bus.Read32(AT.READ, addr);
|
||||
}
|
||||
|
||||
ulong MemA_Read64(uint addr)
|
||||
{
|
||||
ulong ret = MemA_Read32(addr);
|
||||
ret |= (((ulong)MemA_Read32(addr + 4)) << 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void _SetExclusiveMonitors(uint address, int size)
|
||||
{
|
||||
//TODO!!! boring!!
|
||||
|
@ -106,6 +113,16 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
MemA_Write32(addr,float_downcast(val));
|
||||
}
|
||||
|
||||
float MemA_ReadSingle(uint addr)
|
||||
{
|
||||
return float_upcast(MemA_Read32(addr));
|
||||
}
|
||||
|
||||
double MemA_ReadDouble(uint addr)
|
||||
{
|
||||
return double_upcast(MemA_Read64(addr));
|
||||
}
|
||||
|
||||
void MemA_WriteDouble(uint addr, double val)
|
||||
{
|
||||
ulong uval = double_downcast(val);
|
||||
|
@ -443,6 +460,78 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
return result;
|
||||
}
|
||||
|
||||
float _FPAdd(float op1, float op2, bool fpscr_controlled)
|
||||
{
|
||||
//TODO
|
||||
return op1 + op2;
|
||||
}
|
||||
|
||||
double _FPAdd(double op1, double op2, bool fpscr_controlled)
|
||||
{
|
||||
//TODO
|
||||
return op1 + op2;
|
||||
}
|
||||
|
||||
bool _CheckAdvSIMDOrVFPEnabled(bool x, bool y)
|
||||
{
|
||||
//TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint[] __VFPExpandImm32_table;
|
||||
static uint __VFPExpandImm32_calc(uint imm8)
|
||||
{
|
||||
uint a = _.BIT7(imm8);
|
||||
uint B = _.BIT6(imm8)^1;
|
||||
uint b = _.BIT6(imm8);
|
||||
b |= (b << 1); //replicated to 2 bits
|
||||
b |= (b << 2); //replicated to 4 bits
|
||||
b |= (b << 1); //replicated to 5 bits
|
||||
uint cdefgh = imm8 & 0x3F;
|
||||
|
||||
return (a<<31)|(B<<30)|(b<<29)|(cdefgh<<24);
|
||||
}
|
||||
|
||||
static ulong[] __VFPExpandImm64_table;
|
||||
static ulong __VFPExpandImm64_calc(uint imm8)
|
||||
{
|
||||
uint a = _.BIT7(imm8);
|
||||
uint B = _.BIT6(imm8) ^ 1;
|
||||
uint b = _.BIT6(imm8);
|
||||
b |= (b << 1); //replicated to 2 bits
|
||||
b |= (b << 2); //replicated to 4 bits
|
||||
b |= (b << 4); //replicated to 8 bits
|
||||
uint cdefgh = imm8 & 0x3F;
|
||||
|
||||
uint uintret = (a << 31) | (B << 30) | (b << 29) | (cdefgh << 20);
|
||||
ulong ulongret = uintret << 32;
|
||||
return ulongret;
|
||||
}
|
||||
|
||||
uint _VFPExpandImm32(uint imm8)
|
||||
{
|
||||
if(__VFPExpandImm32_table == null)
|
||||
{
|
||||
__VFPExpandImm32_table = new uint[256];
|
||||
for(uint i=0;i<256;i++)
|
||||
__VFPExpandImm32_table[i] = __VFPExpandImm32_calc(i);
|
||||
}
|
||||
|
||||
return __VFPExpandImm32_table[imm8];
|
||||
}
|
||||
|
||||
ulong _VFPExpandImm64(uint imm8)
|
||||
{
|
||||
if (__VFPExpandImm64_table == null)
|
||||
{
|
||||
__VFPExpandImm64_table = new ulong[256];
|
||||
for (uint i = 0; i < 256; i++)
|
||||
__VFPExpandImm64_table[i] = __VFPExpandImm64_calc(i);
|
||||
}
|
||||
|
||||
return __VFPExpandImm64_table[imm8];
|
||||
}
|
||||
|
||||
uint _ARMExpandImm(uint imm12)
|
||||
{
|
||||
//A5-10
|
||||
|
|
|
@ -113,18 +113,29 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
float[] S = new float[32];
|
||||
double[] D = new double[16];
|
||||
|
||||
unsafe uint float_downcast(float f)
|
||||
unsafe static uint float_downcast(float f)
|
||||
{
|
||||
float* fp = &f;
|
||||
return *(uint*)fp;
|
||||
}
|
||||
|
||||
unsafe ulong double_downcast(double f)
|
||||
unsafe static float float_upcast(uint f)
|
||||
{
|
||||
uint* fp = &f;
|
||||
return *(float*)fp;
|
||||
}
|
||||
|
||||
unsafe static ulong double_downcast(double f)
|
||||
{
|
||||
double* fp = &f;
|
||||
return *(ulong*)fp;
|
||||
}
|
||||
|
||||
unsafe static double double_upcast(ulong f)
|
||||
{
|
||||
ulong* fp = &f;
|
||||
return *(double*)fp;
|
||||
}
|
||||
|
||||
public uint SP { get { return r[13]; } set { r[13] = value; } }
|
||||
public uint LR { get { return r[14]; } set { r[14] = value; } }
|
||||
|
@ -140,6 +151,8 @@ namespace BizHawk.Emulation.CPUs.ARM
|
|||
|
||||
|
||||
uint FPSCR;
|
||||
uint _FPSCR_LEN() { return 0; }
|
||||
uint _FPSCR_STRIDE() { return 0; }
|
||||
|
||||
public ARM(ARM_SYS sys, ARM_BUS bus)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue