A64: Implement AXFlag and XAFlag

This commit is contained in:
Lioncash 2019-03-06 17:38:15 -05:00 committed by MerryMage
parent 20ffe568d0
commit aa22db534b
3 changed files with 50 additions and 2 deletions

View file

@ -175,6 +175,7 @@ add_library(dynarmic
frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp
frontend/A64/translate/impl/sys_dc.cpp
frontend/A64/translate/impl/system.cpp
frontend/A64/translate/impl/system_flag_format.cpp
frontend/A64/translate/impl/system_flag_manipulation.cpp
frontend/A64/translate/translate.cpp
frontend/A64/translate/translate.h

View file

@ -87,8 +87,8 @@ INST(RMIF, "RMIF", "10111
//INST(SETF16, "SETF16", "0011101000000000010010nnnnn01101") // ARMv8.4
// System - Flag format instructions
//INST(XAFlag, "XAFlag", "11010101000000000100000000111111") // ARMv8.5
//INST(AXFlag, "AXFlag", "11010101000000000100000001011111") // ARMv8.5
INST(XAFlag, "XAFlag", "11010101000000000100000000111111") // ARMv8.5
INST(AXFlag, "AXFlag", "11010101000000000100000001011111") // ARMv8.5
// SYS: Data Cache
INST(DC_IVAC, "DC IVAC", "110101010000100001110110001ttttt")

View file

@ -0,0 +1,47 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2019 MerryMage
* This software may be used and distributed according to the terms of the GNU
* General Public License version 2 or any later version.
*/
#include "frontend/A64/translate/impl/impl.h"
namespace Dynarmic::A64 {
bool TranslatorVisitor::AXFlag() {
const IR::U32 nzcv = ir.GetNZCVRaw();
const IR::U32 z = ir.And(nzcv, ir.Imm32(0x40000000));
const IR::U32 c = ir.And(nzcv, ir.Imm32(0x20000000));
const IR::U32 v = ir.And(nzcv, ir.Imm32(0x10000000));
const IR::U32 new_z = ir.Or(ir.LogicalShiftLeft(v, ir.Imm8(2)), z);
const IR::U32 new_c = ir.And(ir.And(c, ir.Not(ir.LogicalShiftLeft(v, ir.Imm8(1)))), ir.Imm32(0x20000000));
ir.SetNZCVRaw(ir.Or(new_z, new_c));
return true;
}
bool TranslatorVisitor::XAFlag() {
const IR::U32 nzcv = ir.GetNZCVRaw();
const IR::U32 z = ir.And(nzcv, ir.Imm32(0x40000000));
const IR::U32 c = ir.And(nzcv, ir.Imm32(0x20000000));
const IR::U32 not_z = ir.And(ir.Not(z), ir.Imm32(0x40000000));
const IR::U32 not_c = ir.And(ir.Not(c), ir.Imm32(0x20000000));
const IR::U32 new_n = ir.And(ir.LogicalShiftLeft(not_c, ir.Imm8(2)),
ir.LogicalShiftLeft(not_z, ir.Imm8(1)));
const IR::U32 new_z = ir.And(z, ir.LogicalShiftLeft(c, ir.Imm8(1)));
const IR::U32 new_c = ir.Or(c, ir.LogicalShiftRight(z, ir.Imm8(1)));
const IR::U32 new_v = ir.And(ir.LogicalShiftRight(not_c, ir.Imm8(1)),
ir.LogicalShiftRight(z, ir.Imm8(2)));
const IR::U32 result = ir.Or(ir.Or(ir.Or(new_n, new_z), new_c), new_v);
ir.SetNZCVRaw(result);
return true;
}
} // namespace Dynarmic::A64