Exemplo n.º 1
0
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));
}