void setStateValue(ThreadState& state, Target t, Value v) { if (t >= TargetId::GPR0 && t <= TargetId::GPR31) { assert(v.type == Value::Type::Uint32); state.gpr[t - TargetId::GPR0] = v.uint32Value; } else if (t >= TargetId::FPR0 && t <= TargetId::FPR31) { assert(v.type == Value::Type::Double); state.fpr[t - TargetId::FPR0].value = v.doubleValue; } else if (t >= TargetId::CRF0 && t <= TargetId::CRF7) { assert(v.type == Value::Type::Uint32); setCRF(&state, t - TargetId::CRF0, v.uint32Value); } else if (t == TargetId::XERSO) { assert(v.type == Value::Type::Uint32); state.xer.so = v.uint32Value; } else if (t == TargetId::XEROV) { assert(v.type == Value::Type::Uint32); state.xer.ov = v.uint32Value; } else if (t == TargetId::XERCA) { assert(v.type == Value::Type::Uint32); state.xer.ca = v.uint32Value; } else if (t == TargetId::XERBC) { assert(v.type == Value::Type::Uint32); state.xer.byteCount = v.uint32Value; } else { assert(0); } }
static void cmpGeneric(ThreadState *state, Instruction instr) { Type a, b; uint32_t c; a = state->gpr[instr.rA]; if (flags & CmpImmediate) { if (std::is_signed<Type>::value) { b = sign_extend<16>(instr.simm); } else { b = instr.uimm; } } else { b = state->gpr[instr.rB]; } if (a < b) { c = ConditionRegisterFlag::LessThan; } else if (a > b) { c = ConditionRegisterFlag::GreaterThan; } else { c = ConditionRegisterFlag::Equal; } if (state->xer.so) { c |= ConditionRegisterFlag::SummaryOverflow; } setCRF(state, instr.crfD, c); }
static void fcmpGeneric(ThreadState *state, Instruction instr) { Type a, b; uint32_t c; if (flags & FCmpSingle0) { a = static_cast<Type>(state->fpr[instr.frA].paired0); b = static_cast<Type>(state->fpr[instr.frB].paired0); } else if (flags & FCmpSingle1) { a = static_cast<Type>(state->fpr[instr.frA].paired1); b = static_cast<Type>(state->fpr[instr.frB].paired1); } else { a = static_cast<Type>(state->fpr[instr.frA].paired0); b = static_cast<Type>(state->fpr[instr.frB].paired0); } if (a < b) { c = ConditionRegisterFlag::LessThan; } else if (a > b) { c = ConditionRegisterFlag::GreaterThan; } else if (a == b) { c = ConditionRegisterFlag::Equal; } else { c = ConditionRegisterFlag::Unordered; if (is_signalling_nan(a) || is_signalling_nan(b)) { state->fpscr.vxsnan = 1; if ((flags & FCmpOrdered) && state->fpscr.ve) { state->fpscr.vxvc = 1; } } else if ((flags & FCmpOrdered)) { state->fpscr.vxvc = 1; } } setCRF(state, instr.crfD, c); state->fpscr.cr1 = c; state->fpscr.vx |= state->fpscr.vxvc; state->fpscr.fx |= state->fpscr.vx; }
// Move to Condition Register from XER static void mcrxr(ThreadState *state, Instruction instr) { setCRF(state, instr.crfD, state->xer.crxr); state->xer.crxr = 0; }
// Move Condition Register Field static void mcrf(ThreadState *state, Instruction instr) { setCRF(state, instr.crfD, getCRF(state, instr.crfS)); }