Exemplo n.º 1
0
// Condition Register XOR
static bool
crxor(PPCEmuAssembler& a, Instruction instr)
{
   getTwoCRB(a, instr.crbA, a.eax, instr.crbB, a.ecx);
   a.xor_(a.eax, a.ecx);
   setCRB(a, instr.crbD, a.eax, a.ecx, a.edx);
   return true;
}
// Condition Register XOR
static void
crxor(ThreadState *state, Instruction instr)
{
   uint32_t a, b, d;
   a = getCRB(state, instr.crbA);
   b = getCRB(state, instr.crbB);

   d = a ^ b;
   setCRB(state, instr.crbD, d);
}
// Condition Register NAND
static void
crnand(ThreadState *state, Instruction instr)
{
   uint32_t a, b, d;
   a = getCRB(state, instr.crbA);
   b = getCRB(state, instr.crbB);

   d = ~(a & b);
   setCRB(state, instr.crbD, d);
}
Exemplo n.º 4
0
static void
generateTests(InstructionData *data)
{
   std::vector<size_t> indexCur, indexMax;
   std::vector<bool> flagSet;
   hwtest::TestFile testFile;
   auto complete = false;
   auto completeIndices = false;

   for (auto i = 0; i < data->read.size(); ++i) {
      auto &field = data->read[i];
      indexCur.push_back(0);

      switch (field) {
      case Field::rA:
      case Field::rB:
      case Field::rS:
         indexMax.push_back(gValuesGPR.size());
         break;
      case Field::frA:
      case Field::frB:
      case Field::frC:
      case Field::frS:
         indexMax.push_back(gValuesFPR.size());
         break;
      case Field::crbA:
      case Field::crbB:
         indexMax.push_back(gValuesCRB.size());
         break;
      case Field::simm:
         indexMax.push_back(gValuesSIMM.size());
         break;
      case Field::sh:
         indexMax.push_back(gValuesSH.size());
         break;
      case Field::mb:
         indexMax.push_back(gValuesMB.size());
         break;
      case Field::me:
         indexMax.push_back(gValuesME.size());
         break;
      case Field::uimm:
         indexMax.push_back(gValuesUIMM.size());
         break;
      case Field::XERC:
         indexMax.push_back(gValuesXERC.size());
         break;
      case Field::XERSO:
         indexMax.push_back(gValuesXERSO.size());
         break;
      default:
         assert(false);
      }
   }

   for (auto i = 0; i < data->flags.size(); ++i) {
      flagSet.push_back(false);
   }

   while (!complete) {
      uint32_t gpr = 0, fpr = 0, crf = 0, crb = 0;
      hwtest::TestData test;
      memset(&test, 0, sizeof(hwtest::TestData));

      test.instr = gInstructionTable.encode(data->id);

      for (auto i = 0; i < data->read.size(); ++i) {
         auto index = indexCur[i];

         // Generate read field values
         switch (data->read[i]) {
         case Field::rA:
            test.instr.rA = gpr + hwtest::GPR_BASE;
            test.input.gpr[gpr++] = gValuesGPR[index];
            break;
         case Field::rB:
            test.instr.rB = gpr + hwtest::GPR_BASE;
            test.input.gpr[gpr++] = gValuesGPR[index];
            break;
         case Field::rS:
            test.instr.rS = gpr + hwtest::GPR_BASE;
            test.input.gpr[gpr++] = gValuesGPR[index];
            break;
         case Field::frA:
            test.instr.frA = fpr + hwtest::FPR_BASE;
            test.input.fr[fpr++] = gValuesFPR[index];
            break;
         case Field::frB:
            test.instr.frB = fpr + hwtest::FPR_BASE;
            test.input.fr[fpr++] = gValuesFPR[index];
            break;
         case Field::frC:
            test.instr.frC = fpr + hwtest::FPR_BASE;
            test.input.fr[fpr++] = gValuesFPR[index];
            break;
         case Field::frS:
            test.instr.frS = fpr + hwtest::FPR_BASE;
            test.input.fr[fpr++] = gValuesFPR[index];
            break;
         case Field::crbA:
            test.instr.crbA = (crb++) + hwtest::CRB_BASE;
            setCRB(test.input, test.instr.crbA, gValuesCRB[index]);
            break;
         case Field::crbB:
            test.instr.crbB = (crb++) + hwtest::CRB_BASE;
            setCRB(test.input, test.instr.crbB, gValuesCRB[index]);
            break;
         case Field::simm:
            test.instr.simm = gValuesSIMM[index];
            break;
         case Field::sh:
            test.instr.sh = gValuesSH[index];
            break;
         case Field::mb:
            test.instr.mb = gValuesMB[index];
            break;
         case Field::me:
            test.instr.me = gValuesME[index];
            break;
         case Field::uimm:
            test.instr.uimm = gValuesUIMM[index];
            break;
         case Field::XERC:
            test.input.xer.ca = gValuesXERC[index];
            break;
         case Field::XERSO:
            test.input.xer.so = gValuesXERSO[index];
            break;
         default:
            assert(false);
         }
      }

      // Generate write field values
      for (auto field : data->write) {
         switch (field) {
         case Field::rA:
            test.instr.rA = gpr + hwtest::GPR_BASE;
            gpr++;
            break;
         case Field::rD:
            test.instr.rD = gpr + hwtest::GPR_BASE;
            gpr++;
            break;
         case Field::frD:
            test.instr.frD = fpr + hwtest::FPR_BASE;
            fpr++;
            break;
         case Field::crfD:
            test.instr.crfD = crf + hwtest::CRF_BASE;
            crf++;
            break;
         case Field::crbD:
            test.instr.crbD = crb + hwtest::CRB_BASE;
            crb++;
            break;
         case Field::XERC:
         case Field::XERSO:
         case Field::FCRISI:
         case Field::FCRZDZ:
         case Field::FCRIDI:
         case Field::FCRSNAN:
            break;
         default:
            assert(false);
         }
      }

      testFile.tests.emplace_back(test);

      // Increase indices
      for (auto i = 0; i < indexCur.size(); ++i) {
         indexCur[i]++;

         if (indexCur[i] < indexMax[i]) {
            break;
         } else if (indexCur[i] == indexMax[i]) {
            indexCur[i] = 0;

            if (i == indexCur.size() - 1) {
               completeIndices = true;
            }
         }
      }

      if (completeIndices) {
         if (flagSet.size() == 0) {
            complete = true;
            break;
         }

         completeIndices = false;

         // Do next flag!
         for (auto i = 0; i < flagSet.size(); ++i) {
            if (!flagSet[i]) {
               flagSet[i] = true;
               break;
            } else {
               flagSet[i] = false;

               if (i == flagSet.size() - 1) {
                  complete = true;
                  break;
               }
            }
         }
      }
   }

   // Save tests to file
   auto filename = std::string("tests/cpu/input/") + data->name;
   std::ofstream out { filename, std::ofstream::out | std::ofstream::binary };
   cereal::BinaryOutputArchive archive(out);
   archive(testFile);
}