/**
* pentium.cpp : jni methods in pentium.32.dll. Will not compile 64 bit. Can't use inline assembler.
*
* For instructions on using javah and the C/C++ compiles see:
* http://mindprod.com/jgloss/jni.html#COMPILING
*
* information for Xeon in http://www.intel.com/assets/pdf/appnote/241618.pdf page 41
* Intel numbers bits 0 is least significant on right.
* Copyright: (c) 2004-2017 Roedy Green, Canadian Mind Products
*/
// JNI prototypes generated by javah
#include "pentium.h"
/*
* Class:     com_mindprod_pentium_Pentium
* Method:    cpuIdVendor
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_mindprod_pentium_Pentium_cpuIdVendor
   (JNIEnv * env, jclass theClass )
   {
   jint vendorId[4];
   _asm
   {
         mov   eax,0
         cpuid
         mov   vendorId,ebx        ; GenuineIntel AuthenticAMD
         mov   vendorId+4,edx      ; goofy order eax, edx, ecx.
         mov   vendorId+8,ecx
         mov   vendorId+12,0       ; terminating null
   }
   return  env->NewStringUTF( (char *)vendorId );
   }
/*
* Class:     com_mindprod_pentium_Pentium
* Method:    cpuIdBrand
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_mindprod_pentium_Pentium_cpuIdBrand
   (JNIEnv * env, jclass theClass )
   {
   jint brand[12+1];
   _asm
   {
         mov   eax,0x80000000
         cpuid
         cmp   eax,0x80000004    ; max supported
         jae   hasBrand
         mov   brand,0
         jmp   done
         hasbrand:
         mov   eax,0x80000002
         cpuid
         mov   brand,eax
         mov   brand+4,ebx
         mov   brand+8,ecx
         mov   brand+12,edx
         mov   eax,0x80000003
         cpuid
         mov   brand+16,eax
         mov   brand+20,ebx
         mov   brand+24,ecx
         mov   brand+28,edx
         mov   eax,0x80000004
         cpuid
         mov   brand+32,eax
         mov   brand+36,ebx
         mov   brand+40,ecx
         mov   brand+44,edx
         mov   brand+48,0       ; terminating null
         done:
   }
   return  env->NewStringUTF( (char *)brand );
   }
/*
* Class:     com_mindprod_pentium_Pentium
* Method:    cpuIdStep
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_mindprod_pentium_Pentium_cpuIdStep
   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
         mov   eax,1
         cpuid
         and   eax,0xf              ; in low order 4 bits
   }
   // return with value in eax
   }
/*
* Class:     com_mindprod_pentium_Pentium
* Method:    cpuIdModel
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_mindprod_pentium_Pentium_cpuIdModel
   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
         mov   eax,1
         cpuid
         shr   eax,4         ; in bits 7:4 bits
         and   eax,0xf
   }
   // return with value in eax
   }
/*
* Class:     com_mindprod_pentium_Pentium
* Method:    cpuIdFamily
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_mindprod_pentium_Pentium_cpuIdFamily
   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
         mov   eax,1
         cpuid
         shr   eax,8         ; in low order bits 11:8 bits
         and   eax,0xf
   }
   // return with value in eax
   }
/*
* Class:     com_mindprod_pentium_Pentium
* Method:    cpuSerNo64
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_com_mindprod_pentium_Pentium_cpuSerNo64
   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
         sub   eax,eax     ; check that level 3 CPUID is supported
         cpuid             ; result in ecx:edx
         cmp   eax,3
         jge   hasSerno
         mov   eax,0       ; not Pentium with serial number, return 0.
         mov   edx,0
         jmp   done
         hasSerno:
         mov   eax,1
         cpuid
         mov   eax,ecx
         done:
   }
   // return with result in edx:eax
   }
/*
* Class:     com_mindprod_pentium_Pentium
* Method:    cpuSerNo96
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_mindprod_pentium_Pentium_cpuSerNo96
   (JNIEnv * env, jclass theClass, jint selector)
   {
   _asm
   {
         mov   eax,1         ; check that Xeon 96-bit CPUID is supported
         cpuid               ; flags in ecx:edx, eax= most significant 32 bits
         test  edx,0x40000   ; bit 18 on means serno supported
         jnz   hasSerno
         mov   eax,0         ; not Xeon with serial number, return 0.
         jmp   done
         hasSerno:
         cmp   selector,0
         jne   notMsb
         jmp   done           ; return with most significant 32 bits in eax
         notMsb:
         mov   eax,3
         cpuid
         cmp   selector,1
         jne   notMiddle
         mov   eax,edx        ; edx is the middle 32 bits.
         jmp   done
         notMiddle:
         mov   eax,ecx        ; ecx is low 32 bit
         done:
   }
   // return with result in eax
   }
/*
* Class:     com_mindprod_pentium_Pentium
* Method:    rdtsc
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_com_mindprod_pentium_Pentium_rdtsc
   (JNIEnv * env, jclass theClass )
   {
   _asm
   {
      rdtsc           ; result in edx:eax
   }
   // return with result in edx:eax
   }
// not class, so no final }