int main(int argc, char** argv) { QApplication a(argc, argv); qDebug() << "Hello, world"; MainWindow window; window.show(); Cpu cpu; CpuRam cpuRam; CpuBus cpuBus(&cpuRam); cpu.setMediator(&cpuBus); CartridgeMapper* cartridge = loadCartridgeMapperFromFile("testRoms/instr_misc/rom_singles/03-dummy_reads.nes"); cpuBus.setCartridge(cartridge); while (true) { cpu.tick(); } std::cout << "Done!" << std::endl; return a.exec(); }
void *RunThread(void *cpu_arg) { Cpu *cpu = (Cpu *)cpu_arg; while(!cpu->GetStatus()) { cpu->Exec(1000000); } return NULL; }
TEST(Cpu, SBC_NoUnderflow) { Cpu cpu; ASSERT_EQ(0, cpu.P.read()); cpu.i_sec(); // set carry instruction cpu.A.write(0x01); cpu.i_sbc(0x01); ASSERT_EQ(0, cpu.A.read()); ASSERT_TRUE(cpu.P.has_carry()); ASSERT_TRUE(cpu.P.has_zero()); ASSERT_FALSE(cpu.P.has_negative()); ASSERT_FALSE(cpu.P.has_overflow()); }
TEST(Cpu, SBC_NoUnderflowNoCarryFlag) { Cpu cpu; ASSERT_EQ(0, cpu.P.read()); cpu.A.write(0x02); cpu.i_sbc(0x01); ASSERT_EQ(0, cpu.A.read()); // No underflow, so the carry bit gets set ASSERT_TRUE(cpu.P.has_carry()); ASSERT_TRUE(cpu.P.has_zero()); ASSERT_FALSE(cpu.P.has_negative()); ASSERT_FALSE(cpu.P.has_overflow()); }
TEST(Cpu, SBC_UnderflowNoCarryFlag) { Cpu cpu; ASSERT_EQ(0, cpu.P.read()); // since carry flag is cleared, SBC will subtract 1 more // and, in this case, wrap around cpu.A.write(0x01); cpu.i_sbc(0x01); ASSERT_EQ(0xff, cpu.A.read()); ASSERT_FALSE(cpu.P.has_carry()); ASSERT_FALSE(cpu.P.has_zero()); ASSERT_TRUE(cpu.P.has_negative()); ASSERT_FALSE(cpu.P.has_overflow()); }
TEST(Cpu, ADC_OverflowNoCarry) { Cpu cpu; // ensure flags are cleared ASSERT_EQ(0, cpu.P.read()); cpu.A.write(0xff); cpu.i_adc(0x01); // 0xff + 0x01 overflows to zero ASSERT_EQ(0, cpu.A.read()); ASSERT_TRUE(cpu.P.has_carry()); ASSERT_TRUE(cpu.P.has_zero()); ASSERT_FALSE(cpu.P.has_negative()); ASSERT_FALSE(cpu.P.has_overflow()); }
TEST(Cpu, ADC_Overflow) { Cpu cpu; ASSERT_EQ(0, cpu.P.read()); cpu.i_sec(); // set carry instruction cpu.A.write(0xff); cpu.i_adc(0x01); // 0xff + 0x01 + 1 (carry) overflows to one ASSERT_EQ(1, cpu.A.read()); ASSERT_TRUE(cpu.P.has_carry()); ASSERT_FALSE(cpu.P.has_zero()); ASSERT_FALSE(cpu.P.has_negative()); ASSERT_FALSE(cpu.P.has_overflow()); }
int main(int argc, char** argv){ if(argc < 2){ cerr << "Usage: " << argv[0] << " CpuId" << endl; } unsigned int cpuId = atoi(argv[1]); Mammut mammut; /*******************************************/ /* Idle states power consumption */ /*******************************************/ VirtualCore* vc = mammut.getInstanceTopology()->getCpus().at(cpuId)->getVirtualCore(); Cpu* cpu = mammut.getInstanceTopology()->getCpu(vc->getCpuId()); vector<VirtualCoreIdleLevel*> idleLevels = vc->getIdleLevels(); Domain* fDomain = mammut.getInstanceCpuFreq()->getDomain(vc); if(idleLevels.size() == 0){ cout << "No idle levels supported by CPU " << cpu->getCpuId() << "." << endl; }else{ for(int32_t i = idleLevels.size() - 1; i >= 0 ; i--){ int fd = open("/dev/cpu_dma_latency", O_RDWR); int32_t lat = idleLevels.at(i)->getExitLatency(); write(fd, &lat, sizeof(lat)); /** We compute the base power consumption at each frequency step. **/ vector<Frequency> frequencies; frequencies = fDomain->getAvailableFrequencies(); for(size_t j = 0; j < frequencies.size(); j++){ fDomain->setGovernor(GOVERNOR_USERSPACE); fDomain->setFrequencyUserspace(frequencies.at(j)); CounterCpus* counter = dynamic_cast<CounterCpus*>(mammut.getInstanceEnergy()->getCounter(COUNTER_CPUS)); counter->reset(); sleep(levelTime); mammut::topology::CpuId cpuId = cpu->getCpuId(); cout << idleLevels.at(i)->getName() << " "; cout << frequencies.at(j) << " "; cout << counter->getJoulesCpu(cpuId)/levelTime << " "; cout << counter->getJoulesCores(cpuId)/levelTime << " "; cout << counter->getJoulesDram(cpuId)/levelTime << " "; cout << counter->getJoulesGraphic(cpuId)/levelTime << " "; cout << fDomain->getCurrentVoltage() << " "; cout << endl; } close(fd); } } }
void PanicModule::DistributeError() { if (!IsInitialized()) return; Lapic & lapic = LapicModule::GetGlobal().GetLapic(); Cpu * current = &Cpu::GetCurrent(); DomainList & domains = DomainList::GetGlobal(); for (int i = 0; i < domains.GetCount(); i++) { Domain & domain = domains[i]; for (int j = 0; j < domain.GetThreadCount(); j++) { Cpu * cpu = &domain.GetCpu(j); if (cpu == current) continue; lapic.SendIpi(cpu->GetApicId(), IntVectors::Panic); } } }
TEST(Cpu, SBC_OverflowFlag_Negative) { Cpu cpu; ASSERT_EQ(0, cpu.P.read()); cpu.i_sec(); cpu.A.write(0x01); cpu.i_sbc(0x02); // 1 - 2 = -1 is allowed to be negative, so // the overflow flag should be cleared ASSERT_EQ(0xff, cpu.A.read()); ASSERT_FALSE(cpu.P.has_overflow()); ASSERT_TRUE(cpu.P.has_negative()); ASSERT_FALSE(cpu.P.has_zero()); ASSERT_FALSE(cpu.P.has_carry()); }
TEST(Cpu, SBC_OverflowFlag_Positive) { Cpu cpu; ASSERT_EQ(0, cpu.P.read()); cpu.i_sec(); cpu.A.write(0x01); // 1 cpu.i_sbc(0x80); // -128 // 1 - (-128) = 1 + 128 = 129 // But this overflows in two's complement math: // 0x01 - 0x80 = 0x81 = -127 ASSERT_EQ(0x81, cpu.A.read()); ASSERT_TRUE(cpu.P.has_overflow()); ASSERT_TRUE(cpu.P.has_negative()); ASSERT_FALSE(cpu.P.has_zero()); ASSERT_FALSE(cpu.P.has_carry()); }
double VMHL13Model::next_occuring_event(double now) { /* TODO: update action's cost with the total cost of processes on the VM. */ /* 1. Now we know how many resource should be assigned to each virtual * machine. We update constraints of the virtual machine layer. * * If we have two virtual machine (VM1 and VM2) on a physical machine (PM1). * X1 + X2 = C (Equation 1) * where * the resource share of VM1: X1 * the resource share of VM2: X2 * the capacity of PM1: C * * Then, if we have two process (P1 and P2) on VM1. * X1_1 + X1_2 = X1 (Equation 2) * where * the resource share of P1: X1_1 * the resource share of P2: X1_2 * the capacity of VM1: X1 * * Equation 1 was solved in the physical machine layer. * Equation 2 is solved in the virtual machine layer (here). * X1 must be passed to the virtual machine laye as a constraint value. **/ /* iterate for all virtual machines */ for (VMModel::vm_list_t::iterator iter = VMModel::ws_vms.begin(); iter != VMModel::ws_vms.end(); ++iter) { VirtualMachine *ws_vm = &*iter; Cpu *cpu = ws_vm->p_cpu; xbt_assert(cpu, "cpu-less host"); double solved_value = ws_vm->action_->getVariable()->value; XBT_DEBUG("assign %f to vm %s @ pm %s", solved_value, ws_vm->getName(), ws_vm->getPm()->name().c_str()); // TODO: check lmm_update_constraint_bound() works fine instead of the below manual substitution. // cpu_cas01->constraint->bound = solved_value; xbt_assert(cpu->getModel() == surf_cpu_model_vm); lmm_system_t vcpu_system = cpu->getModel()->getMaxminSystem(); lmm_update_constraint_bound(vcpu_system, cpu->getConstraint(), virt_overhead * solved_value); } /* 2. Calculate resource share at the virtual machine layer. */ adjustWeightOfDummyCpuActions(); /* 3. Ready. Get the next occuring event */ return surf_cpu_model_vm->next_occuring_event(now); }
void Test_ADC(Setter set, Opcode op, bool extra) { const auto expectedCycles = extra ? op.Cycles + 1 : op.Cycles; auto tester = [&] (Byte a, Byte m, Flag c, Byte expA, Flag expC, Flag expZ, Flag expV, Flag expN) { set(m); cpu.A = a; cpu.C = c; cpu.PC = BASE_PC; cpu.Ticks = BASE_TICKS; cpu.Execute(op); EXPECT_EQ(BASE_PC + op.Bytes, cpu.PC); EXPECT_EQ(BASE_TICKS + expectedCycles, cpu.Ticks); EXPECT_EQ(expA, cpu.A); EXPECT_EQ(expC, cpu.C); EXPECT_EQ(expZ, cpu.Z); EXPECT_EQ(expV, cpu.V); EXPECT_EQ(expN, cpu.N); }; tester(0x10, 0x20, 0, 0x30, 0, 0, 0, 0); // pos pos > pos tester(0x10, 0x20, 1, 0x31, 0, 0, 0, 0); // pos pos C > pos tester(0x00, 0x00, 0, 0x00, 0, 1, 0, 0); // Zero tester(0x7F, 0x80, 1, 0x00, 1, 1, 0, 0); // Zero by carry tester(0x80, 0x80, 0, 0x00, 1, 1, 1, 0); // Zero by overflow tester(0x20, 0xF0, 0, 0x10, 1, 0, 0, 0); // Carry w/o overflow w/o sign change tester(0xF0, 0x20, 0, 0x10, 1, 0, 0, 0); // Carry w/o overflow w/ sign change tester(0xA0, 0xA0, 0, 0x40, 1, 0, 1, 0); // Carry with overflow tester(0x70, 0x10, 0, 0x80, 0, 0, 1, 1); // Overflow pos > neg tester(0xB0, 0xB0, 0, 0x60, 1, 0, 1, 0); // Overflow neg > pos tester(0x00, 0xF0, 0, 0xF0, 0, 0, 0, 1); // Negative }
void Test_SBC(Setter set, Opcode op, int extra) { auto tester = [&] (Byte a, Byte m, Flag c, Byte expA, Flag expC, Flag expZ, Flag expV, Flag expN) { set(m); cpu.A = a; cpu.C = c; cpu.PC = BASE_PC; cpu.Ticks = BASE_TICKS; cpu.Execute(op); EXPECT_EQ(BASE_PC + op.Bytes, cpu.PC); EXPECT_EQ(BASE_TICKS + op.Cycles + extra, cpu.Ticks); EXPECT_EQ(expA, cpu.A); EXPECT_EQ(expC, cpu.C); EXPECT_EQ(expZ, cpu.Z); EXPECT_EQ(expV, cpu.V); EXPECT_EQ(expN, cpu.N); }; tester(0x40, 0x20, 1, 0x20, 0, 0, 0, 0); // pos pos > pos tester(0x40, 0x1F, 0, 0x20, 0, 0, 0, 0); // pos pos C > pos tester(0x00, 0x00, 1, 0x00, 0, 1, 0, 0); // Zero tester(0x80, 0x7F, 0, 0x00, 0, 1, 1, 0); // Zero by overflow tester(0x00, 0xFF, 0, 0x00, 1, 1, 0, 0); // Zero by carry tester(0x20, 0x40, 1, 0xE0, 1, 0, 0, 1); // Carry w/o overflow tester(0x20, 0xA0, 1, 0x80, 1, 0, 1, 1); // Carry w/ overflow tester(0x00, 0x00, 0, 0xFF, 1, 0, 0, 1); // Carry by borrow tester(0x20, 0xA0, 1, 0x80, 1, 0, 1, 1); // Overflow pos > neg tester(0x80, 0x20, 1, 0x60, 0, 0, 1, 0); // Overflow neg > pos tester(0x80, 0x00, 1, 0x80, 0, 0, 0, 1); // Negative }
TEST(Cpu, ADC_NoOverflow) { Cpu cpu; ASSERT_EQ(0, cpu.P.read()); cpu.i_sec(); // set carry instruction cpu.A.write(0x7f); cpu.i_adc(0x01); // 0x7f + 0x01 + 1 = 0x81 ASSERT_EQ(0x81, cpu.A.read()); ASSERT_FALSE(cpu.P.has_carry()); ASSERT_FALSE(cpu.P.has_zero()); ASSERT_TRUE(cpu.P.has_negative()); // interpreting inputs as signed two's complement values, we added // a positive to a positive (0x7f + 0x01) and got a negative (0x81) // so we should see the overflow flag get set ASSERT_TRUE(cpu.P.has_overflow()); }
/********* * Model * *********/ void CpuModel::updateActionsStateLazy(double now, double /*delta*/) { CpuAction *action; while ((xbt_heap_size(getActionHeap()) > 0) && (double_equals(xbt_heap_maxkey(getActionHeap()), now, sg_surf_precision))) { action = static_cast<CpuAction*>(xbt_heap_pop(getActionHeap())); XBT_CDEBUG(surf_kernel, "Something happened to action %p", action); if (TRACE_is_enabled()) { Cpu *cpu = static_cast<Cpu*>(lmm_constraint_id(lmm_get_cnst_from_var(getMaxminSystem(), action->getVariable(), 0))); TRACE_surf_host_set_utilization(cpu->getName(), action->getCategory(), lmm_variable_getvalue(action->getVariable()), action->getLastUpdate(), now - action->getLastUpdate()); } action->finish(); XBT_CDEBUG(surf_kernel, "Action %p finished", action); /* set the remains to 0 due to precision problems when updating the remaining amount */ action->setRemains(0); action->setState(SURF_ACTION_DONE); action->heapRemove(getActionHeap()); //FIXME: strange call since action was already popped } if (TRACE_is_enabled()) { //defining the last timestamp that we can safely dump to trace file //without losing the event ascending order (considering all CPU's) double smaller = -1; ActionList *actionSet = getRunningActionSet(); for(ActionList::iterator it(actionSet->begin()), itend(actionSet->end()) ; it != itend ; ++it) { action = static_cast<CpuAction*>(&*it); if (smaller < 0) { smaller = action->getLastUpdate(); continue; } if (action->getLastUpdate() < smaller) { smaller = action->getLastUpdate(); } } if (smaller > 0) { TRACE_last_timestamp_to_dump = smaller; } } return; }
void putCPUinfo() { using namespace Xbyak::util; Cpu cpu; printf("vendor %s\n", cpu.has(Cpu::tINTEL) ? "intel" : "amd"); static const struct { Cpu::Type type; const char *str; } tbl[] = { { Cpu::tMMX, "mmx" }, { Cpu::tMMX2, "mmx2" }, { Cpu::tCMOV, "cmov" }, { Cpu::tSSE, "sse" }, { Cpu::tSSE2, "sse2" }, { Cpu::tSSE3, "sse3" }, { Cpu::tSSSE3, "ssse3" }, { Cpu::tSSE41, "sse41" }, { Cpu::tSSE42, "sse42" }, { Cpu::tPOPCNT, "popcnt" }, { Cpu::t3DN, "3dn" }, { Cpu::tE3DN, "e3dn" }, { Cpu::tSSE4a, "sse4a" }, { Cpu::tSSE5, "sse5" }, { Cpu::tAESNI, "aesni" }, { Cpu::tRDTSCP, "rdtscp" }, { Cpu::tOSXSAVE, "osxsave(xgetvb)" }, { Cpu::tPCLMULQDQ, "pclmulqdq" }, { Cpu::tAVX, "avx" }, { Cpu::tFMA, "fma" }, }; for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { if (cpu.has(tbl[i].type)) printf(" %s", tbl[i].str); } printf("\n"); if (cpu.has(Cpu::tPOPCNT)) { const int n = 0x12345678; // bitcount = 13 const int ok = 13; int r = ((int (*)())(PopCountTest(n).getCode()))(); if (r == ok) { puts("popcnt ok"); } else { printf("popcnt ng %d %d\n", r, ok); } } }
int main(int argc, char* argv[]) { std::string file = "input.txt"; //int program[] = { // PSH, 5, // PSH, 6, // ADD, // POP, // SET, A, 2, // HLT //}; //std::vector<int> p; Cpu c; c.execute(&parse(file)[0]); }
void cmd_exe(char const line[512], Cpu& cpu){ uInt count = 1; if (sscanf(line, ". %u", &count) == EOF && sscanf(line, ".") == EOF){ COMMAND_SYNTAX(); return; } cpu.execute(count); };
void api_cpu_handler(const shared_ptr<restbed::Session> session) { Cpu *cpu; JSONObject obj; JSONValue *output; wstring cpuModel; double cpuCount; double cpuFrequency; cpu = Cpu::getInstance(); cpuModel = s2ws(cpu->getCpuInfo()); cpuCount = cpu->getCoresCount(); cpuFrequency = cpu->getFreq(); obj[L"model"] = new JSONValue(cpuModel); obj[L"count"] = new JSONValue(cpuCount); obj[L"frequency"] = new JSONValue(cpuFrequency); output = new JSONValue(obj); session->close(restbed::OK, ws2s(output->Stringify()), { { "Content-Type", "application/json" } }); }
/* * Print out the current CPU settings as configured either from * the cpufreq sysfs files or the intel_pstate sysfs files. */ void printCpuValues(const Cpu &cpu) { if (Log::isOutputCapable()) { printVersion(); std::ostringstream oss; oss << Color::boldWhite() << " pstate::" << Color::boldGreen() << "CPU_DRIVER -> " << Color::boldCyan() << cpu.getDriver() << std::endl; oss << Color::boldWhite() << " pstate::" << Color::boldGreen() << "CPU_GOVERNOR -> " << Color::boldCyan() << cpu.getGovernor() << std::endl; const int turbo = cpu.getTurboBoost(); oss << Color::boldWhite() << " pstate::" << Color::boldGreen() << (cpu.hasPstate() ? "NO_TURBO -> " : "TURBO_BOOST -> ") << Color::boldCyan() << turbo << " : " << (cpu.hasPstate() ? (turbo == 1 ? "OFF" : "ON") : (turbo == 1 ? "ON" : "OFF")) << std::endl; oss << Color::boldWhite() << " pstate::" << Color::boldGreen() << "CPU_MIN -> " << Color::boldCyan() << cpu.getMinValue() << "% : " << static_cast<int>(cpu.getScalingMinFrequency()) << "KHz" << std::endl; oss << Color::boldWhite() << " pstate::" << Color::boldGreen() << "CPU_MAX -> " << Color::boldCyan() << cpu.getMaxValue() << "% : " << static_cast<int>(cpu.getScalingMaxFrequency()) << "KHz" << std::endl; oss << Color::reset(); std::cout << oss.str(); } }
void CpuModel::updateActionsStateFull(double now, double delta) { CpuAction *action = NULL; ActionList *running_actions = getRunningActionSet(); for(ActionList::iterator it(running_actions->begin()), itNext=it, itend(running_actions->end()) ; it != itend ; it=itNext) { ++itNext; action = static_cast<CpuAction*>(&*it); if (TRACE_is_enabled()) { Cpu *x = static_cast<Cpu*> (lmm_constraint_id(lmm_get_cnst_from_var(getMaxminSystem(), action->getVariable(), 0)) ); TRACE_surf_host_set_utilization(x->getName(), action->getCategory(), lmm_variable_getvalue(action->getVariable()), now - delta, delta); TRACE_last_timestamp_to_dump = now - delta; } action->updateRemains(lmm_variable_getvalue(action->getVariable()) * delta); if (action->getMaxDuration() != NO_MAX_DURATION) action->updateMaxDuration(delta); if ((action->getRemainsNoUpdate() <= 0) && (lmm_get_variable_weight(action->getVariable()) > 0)) { action->finish(); action->setState(SURF_ACTION_DONE); } else if ((action->getMaxDuration() != NO_MAX_DURATION) && (action->getMaxDuration() <= 0)) { action->finish(); action->setState(SURF_ACTION_DONE); } } return; }
void run() { if (executionCounter > 0) { printer.print(" \n"); } savedRam = ram.state; cpu.exec(); // if 'esc' was pressed then it doesn't wait for keypress at the end if (executionCanceled) { executionCanceled = false; } else { getc(stdin); } ram = Ram(); ram.state = savedRam; cpu = Cpu(); redrawScreen(); executionCounter++; }
void Test_Transfer(Getter get, Setter set, Opcode op) { auto tester = [&] (Byte value, Flag expZ, Flag expN) { set(value); cpu.PC = BASE_PC; cpu.Ticks = BASE_TICKS; cpu.Execute(op); EXPECT_EQ(BASE_PC + op.Bytes, cpu.PC); EXPECT_EQ(BASE_TICKS + op.Cycles, cpu.Ticks); EXPECT_EQ(value, get()); EXPECT_EQ(expZ, cpu.Z); EXPECT_EQ(expN, cpu.N); }; tester(0x20, 0, 0); tester(0xA0, 0, 1); tester(0x00, 1, 0); }
void Test_Branch(Setter set, Flag success, Flag failure, Opcode op) { auto tester = [&] (Word pc, Byte offset, Flag c, Word expPC, int extra) { cpu.Memory.SetByteAt(pc, 0xFF); cpu.Memory.SetByteAt(pc + 1, offset); set(c); cpu.PC = pc; cpu.Ticks = BASE_TICKS; cpu.Execute(op); EXPECT_EQ(expPC, cpu.PC); EXPECT_EQ(BASE_TICKS + op.Cycles + extra, cpu.Ticks); }; tester(0x0080, 0x20, failure, 0x0082, 0); // Fail tester(0x0080, 0x20, success, 0x00A0, 1); // Success, positive offset tester(0x0080, 0xE0, success, 0x0060, 1); // Success, negative offset tester(0x00F0, 0x20, success, 0x0110, 3); // Success, positive offset, crossing page tester(0x0110, 0xE0, success, 0x00F0, 3); // Success, negative offset, crossing page }
/* * Grab the current CPU frequencies from /proc/cpuinfo * and pretty print them to the stdout */ void printRealtimeFrequency(const Cpu &cpu) { if (Log::isOutputCapable()) { printVersion(); const std::vector<std::string> frequencies = cpu.getRealtimeFrequencies(); if (!frequencies.empty()) { std::ostringstream oss; const unsigned int size = frequencies.size(); for (unsigned int i = 0; i < size; ++i) { std::string freq = frequencies[i]; oss << Color::boldWhite() << " pstate::" << Color::boldGreen() << "CPU[" << Color::boldMagenta() << i << Color::boldGreen() << "] -> " << Color::boldCyan() << freq.substr(0, freq.size() - 1) << "MHz" << Color::reset() << std::endl; } std::cout << oss.str(); } } }
void Test_Compare(SetterReg setR, SetterMem setM, Opcode op, int extra) { auto tester = [&] (Byte r, Byte m, Flag expC, Flag expZ, Flag expN) { setR(r); setM(m); cpu.PC = BASE_PC; cpu.Ticks = BASE_TICKS; cpu.Execute(op); EXPECT_EQ(BASE_PC + op.Bytes, cpu.PC); EXPECT_EQ(BASE_TICKS + op.Cycles + extra, cpu.Ticks); EXPECT_EQ(expC, cpu.C); EXPECT_EQ(expZ, cpu.Z); EXPECT_EQ(expN, cpu.N); }; tester(0x20, 0x10, 1, 0, 0); // Greater tester(0x20, 0x20, 1, 1, 0); // Equal tester(0x20, 0x40, 0, 0, 1); // Lower tester(0xF0, 0xE0, 1, 0, 0); // Greater tester(0xF0, 0xF0, 1, 1, 0); // Equal tester(0xF0, 0xF8, 0, 0, 1); // Lower }
void putCPUinfo() { using namespace Xbyak::util; Cpu cpu; printf("vendor %s\n", cpu.has(Cpu::tINTEL) ? "intel" : "amd"); static const struct { Cpu::Type type; const char *str; } tbl[] = { { Cpu::tMMX, "mmx" }, { Cpu::tMMX2, "mmx2" }, { Cpu::tCMOV, "cmov" }, { Cpu::tSSE, "sse" }, { Cpu::tSSE2, "sse2" }, { Cpu::tSSE3, "sse3" }, { Cpu::tSSSE3, "ssse3" }, { Cpu::tSSE41, "sse41" }, { Cpu::tSSE42, "sse42" }, { Cpu::tPOPCNT, "popcnt" }, { Cpu::t3DN, "3dn" }, { Cpu::tE3DN, "e3dn" }, { Cpu::tSSE4a, "sse4a" }, { Cpu::tSSE5, "sse5" }, { Cpu::tAESNI, "aesni" }, { Cpu::tRDTSCP, "rdtscp" }, { Cpu::tOSXSAVE, "osxsave(xgetvb)" }, { Cpu::tPCLMULQDQ, "pclmulqdq" }, { Cpu::tAVX, "avx" }, { Cpu::tFMA, "fma" }, { Cpu::tAVX2, "avx2" }, { Cpu::tBMI1, "bmi1" }, { Cpu::tBMI2, "bmi2" }, { Cpu::tLZCNT, "lzcnt" }, { Cpu::tENHANCED_REP, "enh_rep" }, }; for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { if (cpu.has(tbl[i].type)) printf(" %s", tbl[i].str); } printf("\n"); if (cpu.has(Cpu::tPOPCNT)) { const int n = 0x12345678; // bitcount = 13 const int ok = 13; int r = PopCountTest(n).getCode<int (*)()>()(); if (r == ok) { puts("popcnt ok"); } else { printf("popcnt ng %d %d\n", r, ok); } } /* displayFamily displayModel Opteron 2376 10 4 Core2 Duo T7100 6 F Core i3-2120T 6 2A Core i7-2600 6 2A Xeon X5650 6 2C Core i7-3517 6 3A Core i7-3930K 6 2D */ cpu.putFamily(); }
function<void (Byte)> Setter(Word a) { return [=] (Byte value) { cpu.WriteByteAt(a, value); }; }
function<Byte ()> Getter(Word a) { return [=] () { return cpu.ReadByteAt(a); }; }