2016-05-06 21:45:37 +00:00
|
|
|
// Copyright (c) 2012- PPSSPP Project.
|
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, version 2.0 or later versions.
|
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official git repository and contact information can be found at
|
|
|
|
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
|
|
|
|
|
|
|
#include "Core/Config.h"
|
2016-07-02 23:38:30 +00:00
|
|
|
#include "Core/MemMap.h"
|
2016-05-06 21:45:37 +00:00
|
|
|
#include "Core/MIPS/MIPS.h"
|
|
|
|
#include "Core/MIPS/MIPSAnalyst.h"
|
|
|
|
#include "Core/MIPS/MIPSCodeUtils.h"
|
2016-05-09 21:47:56 +00:00
|
|
|
#include "Core/MIPS/IR/IRFrontend.h"
|
2016-05-06 21:45:37 +00:00
|
|
|
#include "Core/MIPS/IR/IRRegCache.h"
|
|
|
|
|
|
|
|
#define _RS MIPS_GET_RS(op)
|
|
|
|
#define _RT MIPS_GET_RT(op)
|
|
|
|
#define _RD MIPS_GET_RD(op)
|
|
|
|
#define _FS MIPS_GET_FS(op)
|
|
|
|
#define _FT MIPS_GET_FT(op)
|
|
|
|
#define _FD MIPS_GET_FD(op)
|
|
|
|
#define _SA MIPS_GET_SA(op)
|
|
|
|
#define _POS ((op>> 6) & 0x1F)
|
|
|
|
#define _SIZE ((op>>11) & 0x1F)
|
|
|
|
#define _IMM16 (signed short)(op & 0xFFFF)
|
|
|
|
#define _IMM26 (op & 0x03FFFFFF)
|
|
|
|
|
|
|
|
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
|
|
|
|
// Currently known non working ones should have DISABLE.
|
|
|
|
|
2021-01-09 19:50:32 +00:00
|
|
|
// #define CONDITIONAL_DISABLE(flag) { Comp_Generic(op); return; }
|
2019-02-03 22:01:51 +00:00
|
|
|
#define CONDITIONAL_DISABLE(flag) if (opts.disableFlags & (uint32_t)JitDisable::flag) { Comp_Generic(op); return; }
|
2016-05-06 21:45:37 +00:00
|
|
|
#define DISABLE { Comp_Generic(op); return; }
|
2018-01-01 01:21:41 +00:00
|
|
|
#define INVALIDOP { Comp_Generic(op); return; }
|
2016-05-06 21:45:37 +00:00
|
|
|
|
|
|
|
namespace MIPSComp {
|
2016-05-09 17:57:18 +00:00
|
|
|
void IRFrontend::Comp_ITypeMem(MIPSOpcode op) {
|
2019-02-03 22:01:51 +00:00
|
|
|
CONDITIONAL_DISABLE(LSU);
|
2016-05-06 21:45:37 +00:00
|
|
|
|
2018-01-01 01:21:41 +00:00
|
|
|
int offset = _IMM16;
|
2016-05-06 21:45:37 +00:00
|
|
|
MIPSGPReg rt = _RT;
|
|
|
|
MIPSGPReg rs = _RS;
|
|
|
|
int o = op >> 26;
|
|
|
|
if (((op >> 29) & 1) == 0 && rt == MIPS_REG_ZERO) {
|
|
|
|
// Don't load anything into $zr
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-07-02 23:38:30 +00:00
|
|
|
CheckMemoryBreakpoint(rs, offset);
|
|
|
|
|
2016-05-06 21:45:37 +00:00
|
|
|
switch (o) {
|
|
|
|
// Load
|
|
|
|
case 35:
|
|
|
|
ir.Write(IROp::Load32, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
|
|
|
case 37:
|
|
|
|
ir.Write(IROp::Load16, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
|
|
|
case 33:
|
|
|
|
ir.Write(IROp::Load16Ext, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
|
|
|
case 36:
|
|
|
|
ir.Write(IROp::Load8, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
|
|
|
case 32:
|
|
|
|
ir.Write(IROp::Load8Ext, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
|
|
|
// Store
|
|
|
|
case 43:
|
|
|
|
ir.Write(IROp::Store32, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
|
|
|
case 41:
|
|
|
|
ir.Write(IROp::Store16, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
|
|
|
case 40:
|
|
|
|
ir.Write(IROp::Store8, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 34: //lwl
|
2018-01-07 20:37:07 +00:00
|
|
|
ir.Write(IROp::Load32Left, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
2016-05-06 21:45:37 +00:00
|
|
|
case 38: //lwr
|
2018-01-07 20:37:07 +00:00
|
|
|
ir.Write(IROp::Load32Right, rt, rs, ir.AddConstant(offset));
|
2018-01-01 01:21:41 +00:00
|
|
|
break;
|
2016-05-06 21:45:37 +00:00
|
|
|
case 42: //swl
|
2018-01-07 20:37:07 +00:00
|
|
|
ir.Write(IROp::Store32Left, rt, rs, ir.AddConstant(offset));
|
|
|
|
break;
|
2016-05-06 21:45:37 +00:00
|
|
|
case 46: //swr
|
2018-01-07 20:37:07 +00:00
|
|
|
ir.Write(IROp::Store32Right, rt, rs, ir.AddConstant(offset));
|
2016-05-06 21:45:37 +00:00
|
|
|
break;
|
2018-01-01 00:41:57 +00:00
|
|
|
|
2016-05-06 21:45:37 +00:00
|
|
|
default:
|
2018-01-01 00:41:57 +00:00
|
|
|
INVALIDOP;
|
2016-05-06 21:45:37 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-09 17:57:18 +00:00
|
|
|
void IRFrontend::Comp_Cache(MIPSOpcode op) {
|
2019-02-03 22:01:51 +00:00
|
|
|
CONDITIONAL_DISABLE(LSU);
|
2018-01-01 00:41:57 +00:00
|
|
|
|
2016-05-06 21:45:37 +00:00
|
|
|
int func = (op >> 16) & 0x1F;
|
|
|
|
|
2020-10-16 07:13:41 +00:00
|
|
|
// See Int_Cache for the definitions.
|
2016-05-06 21:45:37 +00:00
|
|
|
switch (func) {
|
2020-10-16 07:13:41 +00:00
|
|
|
case 24: break;
|
|
|
|
case 25: break;
|
|
|
|
case 27: break;
|
|
|
|
case 30: break;
|
2016-05-06 21:45:37 +00:00
|
|
|
default:
|
2020-10-16 07:13:41 +00:00
|
|
|
// Fall back to the interpreter.
|
2016-05-06 21:45:37 +00:00
|
|
|
DISABLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|