📄 branch_instruction.cpp
字号:
/* -*- C++ -*- */
/**
* Copyright (c) 2005 Zhejiang University, P.R.China
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
///==================================================
/**
* @file Branch_Instruction.h
* @brief
* @author Chenfeng Zhou <ini_autumn@163.com>
*
* Created : <2005-02-24 12:58:27 by Cheney Chow>
* Last update: <2005-03-03 17:59:27 by Cheney Chow>
*
* $Id: Branch_Instruction.cpp,v 1.1 2005/06/16 06:01:43 qilj Exp $
*/
///==================================================
#include "Instr_Flag.h"
#include "Instr_Declare.h"
#include "Parser.h"
#include "Register.h"
#include "Types.h"
#include "Reg_Utils.h"
#include "Utils/Debug.h"
namespace PPC {
PPC_INSTRUCTION_IMPL(op_bx)
{
Core::u32 li;
I_Form_Parser::parse(instr, li);
bool aa = true, lk = false;
// Relative address?
if (!(instr & Op_Flag::AA) ) {
li += GET_CPU().get_pc();
aa = false;
}
if (instr & Op_Flag::LK) {
REG(LR).convert_from_int(GET_CPU().get_pc() + 4);
lk = true;
}
PPC_TRACE_3("bx", (Core::u32*)li, (aa? "AA" : "NO_AA"), (lk? "LK" : "NO_LK"));
GET_CPU().set_npc(li);
}
PPC_INSTRUCTION_IMPL(op_bcx)
{
PPC_u32 BO, BD, BI;
B_Form_Parser::parse(instr, BO, BD, BI);
bool aa = true, lk = false;
if ( !(BO & 4) )
REG(CTR).convert_from_int(REG_TO_INT(REG(CTR)) - 1);
bool bo2 = (BO & 2);
bool bo8 = (BO & 8);
bool cr = REG_BIT_IS_SET(CR, 31 - BI);
bool ctr_ok = (BO & 4) || ((REG_TO_INT(REG(CTR)) != 0) ^ bo2);
bool cond_ok = (BO & 16) || (!(cr ^ bo8));
if (ctr_ok && cond_ok) {
if (!(instr & Op_Flag::AA) ) {
BD += GET_CPU().get_pc();
aa = false;
}
if (instr & Op_Flag::LK) {
REG(LR).convert_from_int(GET_CPU().get_pc() + 4);
lk = true;
}
PPC_TRACE_3("bcx", (Core::u32*)BD, (aa? "AA" : "NO_AA"), (lk? "LK" : "NO_LK"));
GET_CPU().set_npc(BD);
}
else {
PPC_TRACE("bcx: npc not set!\n");
}
}
PPC_INSTRUCTION_IMPL(op_bcctrx)
{
PPC_u32 BO, BD, BI;
X_Form_Parser::parse_xl(instr, BO, BI, BD);
PPC_TRACE_3("bcctrx", BO, BI, BD);
PPC_ASSERT(BD == 0);
PPC_ASSERT(!(BO & 2));
bool bo8 = (BO & 8);
bool cr = REG_BIT_IS_SET(CR, 31 - BI);
if ((BO & 16) || (!(cr ^ bo8))) {
if (instr & Op_Flag::LK)
REG(LR).convert_from_int(GET_CPU().get_pc() + 4);
GET_CPU().set_npc(REG_TO_INT(REG(CTR)) & 0xfffffffc);
PPC_TRACE_3("---bcctrx ", (Core::u32*)GET_CPU().get_npc(), "", "");
}
else
PPC_TRACE("bcctrx: npc not set!\n");
}
PPC_INSTRUCTION_IMPL(op_bclrx)
{
PPC_u32 BO, BD, BI;
X_Form_Parser::parse_xl(instr, BO, BI, BD);
bool lk = false;
PPC_ASSERT(BD == 0);
if ( !(BO & 4) )
REG(CTR).convert_from_int(REG_TO_INT(REG(CTR)) - 1);
bool bo2 = (BO & 2);
bool bo8 = (BO & 8);
bool cr = REG_BIT_IS_SET(CR, 31 - BI);
bool ctr_ok = (BO & 4) || ((REG_TO_INT(REG(CTR)) != 0) ^ bo2);
bool cond_ok = (BO & 16) || (!(cr ^ bo8));
if (ctr_ok && cond_ok) {
BD = (REG_TO_INT(REG(LR)) & 0xfffffffc);
if (instr & Op_Flag::LK) {
REG(LR).convert_from_int(GET_CPU().get_pc() + 4);
lk = true;
}
PPC_TRACE_3("bclrx", (Core::u32*)BD, "", (lk? "LK" : "NO_LK"));
GET_CPU().set_npc(BD);
}
else {
PPC_TRACE("bclrx: npc not set!\n");
}
}
} //namespace PPC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -