Initial port ot Igor Stasenko's AsmJit
authorJan Vrany <jan.vrany@fit.cvut.cz>
Tue, 15 Dec 2015 23:18:02 +0000
changeset 3 483729eb4432
parent 2 88445baa732f
child 4 f2d0d2859193
Initial port ot Igor Stasenko's AsmJit
asm/AJAlignmentInstruction.st
asm/AJAssembler.st
asm/AJBaseReg.st
asm/AJCallArgument.st
asm/AJCallCleanup.st
asm/AJCallInfo.st
asm/AJCdeclCallInfo.st
asm/AJConstants.st
asm/AJData.st
asm/AJGeneratedCode.st
asm/AJImmediate.st
asm/AJInstruction.st
asm/AJInstructionDecoration.st
asm/AJJumpInstruction.st
asm/AJJumpLabel.st
asm/AJLineStream.st
asm/AJMMRegister.st
asm/AJMem.st
asm/AJOperand.st
asm/AJRegister.st
asm/AJReleaseTemps.st
asm/AJReserveTemp.st
asm/AJRoutineEpilogue.st
asm/AJRoutinePrologue.st
asm/AJRoutineStackManager.st
asm/AJStackAlignmentTests.st
asm/AJStackInstruction.st
asm/AJStdCallCallInfo.st
asm/AJx64Assembler.st
asm/AJx64AssemblerTests.st
asm/AJx64Instruction.st
asm/AJx64InstructionDescription.st
asm/AJx64JumpInstruction.st
asm/AJx64RipRegister.st
asm/AJx86Assembler.st
asm/AJx86AssemblerTests.st
asm/AJx86GPRegister.st
asm/AJx86Instruction.st
asm/AJx86InstructionDescription.st
asm/AJx86JumpInstruction.st
asm/AJx86RegisterTests.st
asm/AJx86Registers.st
asm/AJx87Register.st
asm/AJxMMRegister.st
asm/Make.proto
asm/Make.spec
asm/Makefile.init
asm/abbrev.stc
asm/asm.rc
asm/bc.mak
asm/bmake.bat
asm/extensions.st
asm/jv_dragonfly_asm.st
asm/libInit.cc
asm/mingwmake.bat
asm/vcmake.bat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJAlignmentInstruction.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,114 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJAlignmentInstruction
+	instanceVariableNames:'alignTo'
+	classVariableNames:''
+	poolDictionaries:'AJConstants'
+	category:'AsmJit-Instructions'
+!
+
+AJAlignmentInstruction comment:'I am a pseudo instruction used to align the following instruction to a multiple of a given byte number.

Example:
	asm := AJx64Assembler noStackFrame.
	
	"align the following instruction to a word (2bytes)"
	asm alignWord.
	asm inc: asm RAX.
	
	"align the following instruction to a double (4bytes)"
	asm alignDouble.
	asm inc: asm RAX.
	
	"align the following instruction to a QuadWord (8bytes)"
	asm alignQuad.
	asm inc: asm RAX.
	
	"align the following instruction to a multiple of an arbirary count"
	asm align: 64.
	asm inc: asm RAX.'
+!
+
+!AJAlignmentInstruction class methodsFor:'instance creation'!
+
+align: byteSize
+    ^ self new align: byteSize
+!
+
+alignDouble
+    ^ self new alignDouble
+!
+
+alignQuad
+    ^ self new alignQuad
+!
+
+alignWord
+    ^ self new alignWord
+! !
+
+!AJAlignmentInstruction methodsFor:'accessing'!
+
+align
+    ^ alignTo
+!
+
+align: bytesSize
+    "align the data to the given byte count"
+    alignTo := bytesSize
+!
+
+name
+    ^ String streamContents: [ :s|
+        self printSelfOn: s]
+!
+
+printSelfOn: aStream  
+    self align <= 1 ifTrue: [ ^ self ].
+    
+    aStream nextPut: $|.
+    self align <= 8 
+        ifTrue: [
+            self align timesRepeat: [
+                aStream nextPutAll: '----|']]
+        ifFalse: [
+            aStream 
+                nextPutAll: (self align asString padded: #left to: 4 with: $ );
+                nextPut: $|]
+! !
+
+!AJAlignmentInstruction methodsFor:'alignment'!
+
+alignByte
+    self align: 1
+!
+
+alignDouble
+    self align: 4
+!
+
+alignQuad
+    self align: 8
+!
+
+alignWord
+    self align: 2
+! !
+
+!AJAlignmentInstruction methodsFor:'emitting code'!
+
+emitCode: asm
+    | padding |
+    
+    padding := self paddingForPosition: position.
+    
+    "new machine code: | padding |"
+    machineCode := ByteArray new: padding .
+!
+
+paddingForPosition: aPositionNumber
+    | padding |
+    
+    padding := aPositionNumber \\ self align.
+    padding = 0 
+        ifFalse: [ padding := self align - padding ].
+        
+    ^ padding
+! !
+
+!AJAlignmentInstruction methodsFor:'initialize-release'!
+
+initialize 
+    super initialize.
+    self alignByte.
+! !
+
+!AJAlignmentInstruction methodsFor:'visitor'!
+
+accept: anObject
+    self shouldBeImplemented 
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJAssembler.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,14 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#AJAssembler
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Core'
+!
+
+AJAssembler comment:''
+!
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJBaseReg.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,129 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJOperand subclass:#AJBaseReg
+	instanceVariableNames:'size code name'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Operands'
+!
+
+AJBaseReg comment:'AJBaseReg  -- abstract superclass of all register operands.

Instance Variables:
	size	<Number>  Width in bytes (1, 2, 4, 8...)
	code	<Integer>  Non-negative integer, encoding varies with subclass. For AJx86GPRegisters, ten bits: xyttttnnnn
						where nnnn is the register number 0-15, tttt is the "type", which encodes size as a power of 2. 
						Higher types are used in other subclasses.
						If y is 1, REX prefix is required to encode this register.
						If x is 1, this register cannot be used when any REX prefix is present in the instruction.
	name	<Symbol>  Name by which this register may be referenced in instructions'
+!
+
+!AJBaseReg class methodsFor:'instance creation'!
+
+code: aRegisterCode name: aSymbol
+    ^ self basicNew initializeWithCode: aRegisterCode name: aSymbol
+! !
+
+!AJBaseReg methodsFor:'accessing'!
+
+annotation: anObject
+    "registers gereally are used as single instances, hence putting
+    an annotation on the default register will change the annotation
+    for all the users. To avoid that, the receiver is copied first"
+    ^ self copy
+        basicAnnotation: anObject;
+        yourself
+!
+
+code
+    "Answer the value of code"
+
+    ^ code
+!
+
+code: anObject
+    "Set the value of code"
+
+    code := anObject
+!
+
+description
+    ^ String streamContents: [ :s | self descriptionOn: s ].
+!
+
+index
+    ^ code bitAnd: RegCodeMask
+!
+
+influencingRegisters
+    ^ #()
+!
+
+name
+    ^ name
+!
+
+size
+    ^ size
+!
+
+type
+    ^ code bitAnd: RegTypeMask
+! !
+
+!AJBaseReg methodsFor:'comparing'!
+
+= otherReg
+
+    ^ (self class == otherReg class) and: [ code = otherReg code ]
+!
+
+hash
+    ^ code hash
+! !
+
+!AJBaseReg methodsFor:'initialize-release'!
+
+initializeWithCode: aRegisterCode name: aSymbol
+    super initialize.
+    self code: aRegisterCode.	"Also sets size"
+    name := aSymbol
+! !
+
+!AJBaseReg methodsFor:'printing'!
+
+descriptionOn: aStream
+    self subclassResponsibility
+! !
+
+!AJBaseReg methodsFor:'private'!
+
+basicAnnotation: anObject
+    "private setter"
+    annotation := anObject
+! !
+
+!AJBaseReg methodsFor:'testing'!
+
+isGeneralPurpose
+    self subclassResponsibility 
+!
+
+isUpperBank
+    "Used for emitting the REX Prefix Byte on 64bit machines"
+    ^ self index > 7
+!
+
+isX86
+    self subclassResponsibility
+!
+
+prohibitsRex
+    "Answer true if this register cannot be used in any instruction that has a REX prefix.
+    Of the general-purpose registers, this is true only of SPL, BPL, SIL, DIL."
+
+    ^ (code & RegProhibitsRexMask) ~~ 0
+!
+
+requiresRex 
+    "Answer true if use of this register requires that the instruction have a REX prefix.
+    This can be because the register cannot be accessed except with REX (high bank or 64-only low byte)
+    or because the register is 64-bits wide"
+    
+    ^(code & RegRequiresRexMask) ~~ 0
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJCallArgument.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,51 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJStackInstruction subclass:#AJCallArgument
+	instanceVariableNames:'size stackOffset first'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-StackManagement'
+!
+
+AJCallArgument comment:''
+!
+
+!AJCallArgument methodsFor:'accessing'!
+
+instructionName
+    ^ #push
+!
+
+name
+    ^ 'argument push:'
+!
+
+size
+
+    ^ size 
+!
+
+size: aSmallInteger 
+
+    size := aSmallInteger
+!
+
+stackOffset: anOffset
+    stackOffset := anOffset 
+! !
+
+!AJCallArgument methodsFor:'function calls'!
+
+prepareCallAlignments
+
+    callInfo noticeArgument: self
+! !
+
+!AJCallArgument methodsFor:'visitor'!
+
+accept: anObject
+    ^ anObject visitCallArgument: self  
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJCallCleanup.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,33 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJStackInstruction subclass:#AJCallCleanup
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-StackManagement'
+!
+
+AJCallCleanup comment:''
+!
+
+!AJCallCleanup methodsFor:'accessing'!
+
+name
+    ^ 'call cleanup'
+! !
+
+!AJCallCleanup methodsFor:'function calls'!
+
+prepareCallAlignments
+
+    callInfo callCleanup: self
+! !
+
+!AJCallCleanup methodsFor:'visitor'!
+
+accept: anObject
+    ^ anObject visitCallCleanup: self
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJCallInfo.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,87 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#AJCallInfo
+	instanceVariableNames:'asm stackAlignment stackSize arguments callCleanup prepareForCall
+		noCleanup alignInsertionPoint'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-StackManagement'
+!
+
+AJCallInfo comment:''
+!
+
+!AJCallInfo methodsFor:'accessing'!
+
+alignment: aStackAlignment
+    stackAlignment := aStackAlignment
+!
+
+alignmentInsertionPoint: instruction
+    alignInsertionPoint := instruction
+!
+
+asm: assembler
+    asm := assembler
+!
+
+callCleanup: aCallCleanup
+    self assert: callCleanup isNil.
+    
+    callCleanup := aCallCleanup 
+!
+
+defaultArgumentSize
+    self subclassResponsibility 
+!
+
+disableCleanup 
+    noCleanup := true
+!
+
+name
+    ^ 'call info' 
+!
+
+noCleanup 
+    ^ noCleanup 
+!
+
+noticeArgument: aCallArgument
+
+    arguments add: aCallArgument.
+    stackSize := stackSize + aCallArgument size.
+!
+
+stackSize
+    ^ stackSize
+!
+
+stackSize: anObject
+    stackSize := anObject
+! !
+
+!AJCallInfo methodsFor:'initialize-release'!
+
+initialize
+    arguments := OrderedCollection new.
+    stackSize := 0.
+    stackAlignment := 1.
+    noCleanup := false.
+! !
+
+!AJCallInfo methodsFor:'pushing args'!
+
+push: anArgument
+    
+    asm pushArgument: anArgument forCall: self.
+! !
+
+!AJCallInfo methodsFor:'testing'!
+
+needsAlignment
+    ^ stackAlignment > 1
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJCdeclCallInfo.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,81 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJCallInfo subclass:#AJCdeclCallInfo
+	instanceVariableNames:'savedSP'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-StackManagement'
+!
+
+AJCdeclCallInfo comment:''
+!
+
+!AJCdeclCallInfo methodsFor:'accessing'!
+
+defaultArgumentSize
+    ^ 4
+! !
+
+!AJCdeclCallInfo methodsFor:'emitting code'!
+
+alignedCleanup
+
+    asm
+        mov: savedSP to: asm ESP.
+        
+    asm releaseTemps: 1 "release our temp afterwards"  
+!
+
+emitAlignment
+    | instructions |
+    
+    instructions := asm
+        instructionsFor: [ 
+            asm
+                decorateWith: 'align stack'
+                during: [ 
+                    savedSP := asm reserveTemp annotation: 'saved SP'.
+                    asm mov: asm ESP to: savedSP.
+                    stackSize > 0
+                        ifTrue: [ asm sub: asm ESP with: (stackSize asUImm annotation: 'stack size') ].
+                    asm
+                        and: asm ESP with: stackAlignment - 1;
+                        neg: asm ESP;
+                        add: asm ESP with: savedSP ] ].
+    
+    asm insert: instructions after: alignInsertionPoint.
+    self emitCleanup
+!
+
+emitAlignmentIfNeeded
+    | alignment |
+    
+    self needsAlignment
+        ifTrue: [ ^ self emitAlignment ].
+        
+    self emitCleanup
+!
+
+emitCleanup
+    noCleanup ifTrue: [ ^ self ].
+    
+    asm insert: 
+    (
+            asm instructionsFor: [
+            self needsAlignment 
+                ifTrue: [ self alignedCleanup ]
+                ifFalse: [ self normalCleanup ]  			
+        ]
+
+    ) after: callCleanup
+!
+
+normalCleanup 
+    stackSize > 0 ifTrue: [
+        asm
+            add: asm ESP with: stackSize 
+    ]
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJConstants.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,246 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+SharedPool subclass:#AJConstants
+	instanceVariableNames:''
+	classVariableNames:'CcA CcABOVE CcABOVEEQUAL CcAE CcB CcBE CcBELOW CcBELOWEQUAL CcC
+		CcE CcEQUAL CcFPNOTUNORDERED CcFPUNORDERED CcG CcGE CcGREATER
+		CcGREATEREQUAL CcL CcLE CcLESS CcLESSEQUAL CcNA CcNAE CcNB CcNBE
+		CcNC CcNE CcNEGATIVE CcNG CcNGE CcNL CcNLE CcNO CcNOCONDITION
+		CcNOOVERFLOW CcNOTEQUAL CcNOTSIGN CcNOTZERO CcNP CcNS CcNZ CcO
+		CcOVERFLOW CcP CcPARITYEVEN CcPARITYODD CcPE CcPO CcPOSITIVE CcS
+		CcSIGN CcZ CcZERO InstCMOVA InstJA O64Only OFM1 OFM10 OFM2 OFM24
+		OFM248 OFM4 OFM48 OFM4810 OFM8 OG16 OG163264 OG32 OG3264 OG64 OG8
+		OG8163264 OIMM OMEM OMM OMMMEM OMMXMM OMMXMMMEM ONOREX OXMM
+		OXMMMEM OpImm OpLabel OpMem OpNONE OpREG PrefetchNTA PrefetchT0
+		PrefetchT1 PrefetchT2 RIDEAX RIDEBP RIDEBX RIDECX RIDEDI RIDEDX
+		RIDESI RIDESP RegCodeMask RegGPB RegGPD RegGPQ RegGPW
+		RegHighByteMask RegMM RegProhibitsRexMask RegRequiresRexMask
+		RegTypeMask RegX87 RegXMM SegmentCS SegmentDS SegmentES SegmentFS
+		SegmentGS SegmentNONE SegmentSS SizeByte SizeDQWord SizeDWord
+		SizeQWord SizeTWord SizeWord'
+	poolDictionaries:''
+	category:'AsmJit-Core'
+!
+
+AJConstants comment:''
+!
+
+!AJConstants class methodsFor:'initialization'!
+
+initOpCodes
+
+
+  " x86 "
+  OG8          := 16r01.
+  OG16         := 16r02.
+  OG32         := 16r04.
+  OG64         := 16r08.
+  OMEM         := 16r40.
+  OIMM         := 16r80.
+
+  O64Only      := 16r100.
+
+  OG8163264    := OG64  + OG32  + OG16  + OG8.
+  OG163264     := OG64  + OG32  + OG16.
+  OG3264       := OG64  + OG32.
+
+  " x87"
+  OFM1        := 16r01.
+  OFM2        := 16r02.
+  OFM4        := 16r04.
+  OFM8        := 16r08.
+  OFM10       := 16r10.
+
+  OFM24       := OFM2 + OFM4.
+  OFM248      := OFM2 + OFM4 + OFM8.
+  OFM48       := OFM4 + OFM8.
+  OFM4810     := OFM4 + OFM8 + OFM10.
+
+  " mm|xmm"
+  ONOREX      := 16r01. " Used by MMX/SSE instructions. OG8 is never used for them "
+  OMM         := 16r10.
+  OXMM        := 16r20.
+
+  OMMMEM      := OMM   + OMEM.
+  OXMMMEM     := OXMM  + OMEM.
+  OMMXMM      := OMM   + OXMM.
+  OMMXMMMEM   := OMM   + OXMM  + OMEM.
+!
+
+initialize
+
+    "AJConstants initialize"
+    
+    "Operand is none, used only internally."
+    OpNONE := 0.
+    "Operand is register"
+    OpREG := 1.
+    "Operand is memory"
+    OpMem := 2.
+    "Operand is immediate."
+    OpImm := 3.
+    "Operand is label. "
+    OpLabel := 4.
+
+    RegTypeMask := 16rF0.
+    RegCodeMask := 16r0F.
+    RegRequiresRexMask := 16r100.
+    RegProhibitsRexMask := 16r200.
+    RegHighByteMask := 2r111100.
+    
+    "1 byte size."
+    SizeByte := 1.
+    "2 bytes size."
+    SizeWord := 2.
+    "4 bytes size."
+    SizeDWord := 4.
+    "8 bytes size."
+    SizeQWord := 8.
+    "10 bytes size."
+    SizeTWord := 10.
+    "16 bytes size."
+    SizeDQWord := 16.
+
+
+    "ID for AX/EAX/RAX registers."
+    RIDEAX := 0.
+    "ID for CX/ECX/RCX registers."
+    RIDECX := 1.
+    "ID for DX/EDX/RDX registers."
+    RIDEDX := 2.
+    "ID for BX/EBX/RBX registers."
+    RIDEBX := 3.
+    "ID for SP/ESP/RSP registers."
+    RIDESP := 4.
+    "ID for BP/EBP/RBP registers."
+    RIDEBP := 5.
+    "ID for SI/ESI/RSI registers."
+    RIDESI := 6.
+    "ID for DI/EDI/RDI registers."
+    RIDEDI := 7.
+
+    "8 bit general purpose register type."
+    RegGPB := 16r00.
+    "16 bit general purpose register type."
+    RegGPW := 16r10.
+    "32 bit general purpose register type."
+    RegGPD := 16r20.
+    "64 bit general purpose register type. "
+    RegGPQ := 16r30.
+    "X87 (FPU) register type. "
+    RegX87 := 16r50.
+    "64 bit mmx register type."
+    RegMM := 16r60.
+    "128 bit sse register type."
+    RegXMM := 16r70.
+
+    "Segment override prefixes."
+    
+    "No segment override prefix."
+    SegmentNONE := 0.
+    "Use 'cs' segment override prefix."
+    SegmentCS := 1.
+    "Use 'ss' segment override prefix."
+    SegmentSS := 2.
+    "Use 'ds' segment override prefix."
+    SegmentDS := 3.
+    "Use 'es' segment override prefix."
+    SegmentES := 4.
+    "Use 'fs' segment override prefix."
+    SegmentFS := 5.
+    "Use 'gs' segment override prefix."
+    SegmentGS := 6.
+  
+    self initializePrefetchHints.
+    self initializeConditionCodes.
+    self initOpCodes.
+    
+!
+
+initializeConditionCodes
+
+    "Condition codes."
+
+    "No condition code."
+    CcNOCONDITION  := -1.
+
+    "Condition codes from processor manuals."
+    CcA             := 16r7.
+    CcAE            := 16r3.
+    CcB             := 16r2.
+    CcBE            := 16r6.
+    CcC             := 16r2.
+    CcE             := 16r4.
+    CcG             := 16rF.
+    CcGE            := 16rD.
+    CcL             := 16rC.
+    CcLE            := 16rE.
+    CcNA            := 16r6.
+    CcNAE           := 16r2.
+    CcNB            := 16r3.
+    CcNBE           := 16r7.
+    CcNC            := 16r3.
+    CcNE            := 16r5.
+    CcNG            := 16rE.
+    CcNGE           := 16rC.
+    CcNL            := 16rD.
+    CcNLE           := 16rF.
+    CcNO            := 16r1.
+    CcNP            := 16rB.
+    CcNS            := 16r9.
+    CcNZ            := 16r5.
+    CcO             := 16r0.
+    CcP             := 16rA.
+    CcPE            := 16rA.
+    CcPO            := 16rB.
+    CcS             := 16r8.
+    CcZ             := 16r4.
+
+    " Simplified condition codes"
+    CcOVERFLOW      := 16r0.
+    CcNOOVERFLOW   := 16r1.
+    CcBELOW         := 16r2.
+    CcABOVEEQUAL   := 16r3.
+    CcEQUAL         := 16r4.
+    CcNOTEQUAL     := 16r5.
+    CcBELOWEQUAL   := 16r6.
+    CcABOVE         := 16r7.
+    CcSIGN          := 16r8.
+    CcNOTSIGN      := 16r9.
+    CcPARITYEVEN   := 16rA.
+    CcPARITYODD    := 16rB.
+    CcLESS          := 16rC.
+    CcGREATEREQUAL := 16rD.
+    CcLESSEQUAL    := 16rE.
+    CcGREATER       := 16rF.
+
+    "aliases"
+    CcZERO          := 16r4.
+    CcNOTZERO      := 16r5.
+    CcNEGATIVE      := 16r8.
+    CcPOSITIVE      := 16r9.
+
+    "x87 floating point only"
+    CcFPUNORDERED  := 16.
+    CcFPNOTUNORDERED := 17.
+
+!
+
+initializePrefetchHints
+
+    "Prefetch hints."
+
+    "Prefetch to L0 cache."
+    PrefetchT0 := 1.
+    "Prefetch to L1 cache."
+    PrefetchT1 := 2.
+    "Prefetch to L2 cache."
+    PrefetchT2  := 3.
+    "Prefetch using NT hint."
+    PrefetchNTA := 0.
+! !
+
+
+AJConstants initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJData.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,87 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJData
+	instanceVariableNames:'data alignment'
+	classVariableNames:''
+	poolDictionaries:'AJConstants'
+	category:'AsmJit-Instructions'
+!
+
+AJData comment:'I represent a pure data section in an assembly instruction stream.

Example:
	asm := AJx64Assembler noStackFrame.
	
	"add a raw byte"
	asm db: 16rFF.
	
	"add a raw word"
	asm dw: #[16r34 16r12].
	
	"add a raw double"
	asm dw: #[16r78 16r56 16r34 16r12].
	
	"add a arbitrary sized data section with a byteArray"
	asm data: #[1 2 3 4 5 6 7 8 9 10 11 12 ].'
+!
+
+!AJData class methodsFor:'instance creation'!
+
+byte: aByteValue
+    ^ self data: (ByteArray with: aByteValue)
+!
+
+data: aDataByteArray
+    ^ self new
+        data: aDataByteArray;
+        yourself
+!
+
+label: aLabel data: aDataByteArray
+    ^ self new
+        label: aLabel;
+        data: aDataByteArray;
+        yourself
+! !
+
+!AJData methodsFor:'accessing'!
+
+data
+    ^ machineCode
+!
+
+data: aByteArray
+    "the will be put in the executable."
+    machineCode := aByteArray
+!
+
+name
+    name ifNotNil: [ ^ name ].
+    
+    "standard data sections"
+    self is8 ifTrue: [ ^ 'db' ].
+    self is16 ifTrue: [ ^ 'dw' ].
+    self is32 ifTrue: [ ^ 'dd' ].
+!
+
+size
+    ^ self data size
+! !
+
+!AJData methodsFor:'emitting code'!
+
+emitCode: asm
+    machineCode ifNil: [ machineCode := #[] ]
+! !
+
+!AJData methodsFor:'testing'!
+
+is16
+    ^ self size = 2
+!
+
+is32
+    ^ self size = 4
+!
+
+is64
+    ^ self size = 8
+!
+
+is8
+    ^ self size = 1
+! !
+
+!AJData methodsFor:'visitor'!
+
+accept: anObject
+    anObject instructionData: self
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJGeneratedCode.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,108 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#AJGeneratedCode
+	instanceVariableNames:'bytes labels'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Core'
+!
+
+AJGeneratedCode comment:''
+!
+
+!AJGeneratedCode class methodsFor:'instance creation'!
+
+fromInstructions: instructions
+    ^ self new fromInstructions: instructions
+! !
+
+!AJGeneratedCode methodsFor:'accessing'!
+
+bytes
+    ^ bytes
+!
+
+bytes: aBytes 
+
+    bytes := aBytes
+    
+!
+
+labels: aLabels
+
+    "turn labels into a simple name->offset pairs"
+    aLabels keysAndValuesDo: [:name :lbl |
+        labels at: name put: lbl paddedOffset ].
+        
+!
+
+offsetAt: aLabelName
+    ^ labels at: aLabelName
+! !
+
+!AJGeneratedCode methodsFor:'initialize-release'!
+
+fromInstructions: instructions
+    
+    bytes := ByteArray new: 100 streamContents: [:stream|
+        instructions do: [ :each |
+            each extractLabels: [:name :pos | labels at: name put: pos ].
+            each storeOn: stream ]].
+!
+
+initialize
+    labels := Dictionary new.
+    
+! !
+
+!AJGeneratedCode methodsFor:'output'!
+
+dumpWithLabels
+
+    "dump the native code , interspersed with labels"
+    
+    | offsets i str |
+    
+    offsets := OrderedCollection new.
+
+    labels keysAndValuesDo: [ :name :offset |
+        offsets add: (offset -> name)
+    ].
+
+    offsets := offsets sort: [:a :b | a key < b key ].
+    
+    str := String new writeStream.
+    i := 0.
+    
+    offsets do: [:offset |
+        i to: offset key -1 do: [:x | str nextPutAll: ((bytes at: i+1) printStringBase: 16 nDigits: 2) ; space. i:=i+1. ].
+        str cr; nextPutAll: offset value; cr.
+    ].
+
+    i to: bytes size-1 do: [:x | str nextPutAll: ((bytes at: i+1) printStringBase: 16 nDigits: 2) ; space. i := i + 1] .
+    ^ str contents
+!
+
+saveToFile
+    self saveToFile: 'asm.bin'
+!
+
+saveToFile: fileName
+
+    (FileStream forceNewFileNamed: fileName)  
+        nextPutAll: bytes;
+        close  
+! !
+
+!AJGeneratedCode methodsFor:'printing'!
+
+printOn: aStream
+
+    bytes notNil ifTrue: [
+        aStream nextPutAll: self dumpWithLabels
+        
+        ]
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJImmediate.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,217 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJOperand subclass:#AJImmediate
+	instanceVariableNames:'label size isUnsigned relocMode value'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Operands'
+!
+
+AJImmediate comment:'I am an immediate (constant integer) operand used by the assembler.

Example:
	"create an immediate from an integer"
	1 asImm.
	"implicitely use an immediate in an assembly instrution"
	asm := AJx64Assembler new.
	asm add: 1 to: asm RAX.
	'
+!
+
+!AJImmediate class methodsFor:'as yet unclassified'!
+
+ivalue: aValue
+    ^ self new
+        ivalue: aValue
+! !
+
+!AJImmediate methodsFor:'accessing'!
+
+extractLabels: aBlock
+
+    label ifNotNil: [ label extractLabels: aBlock ]    
+!
+
+ivalue: aValue
+    "signed integer value"
+    value := aValue.
+    isUnsigned := false.
+!
+
+label: aLabelName
+
+    label := aLabelName
+!
+
+relocMode
+    ^ relocMode ifNil: [#RelocNone ]
+!
+
+size
+    ^ size
+!
+
+size: aSize
+    size := aSize
+!
+
+sizeFor: anOperand
+    "Check if I am a valid size to be used together with anOperand
+    If so, I will use as much size as it"
+    self assert: (self fitsInSize: anOperand size).
+    ^anOperand size
+!
+
+uvalue: aValue
+    "unsigned value"
+    self assert: (aValue >=0).
+    value := aValue.
+    isUnsigned := true.
+!
+
+value
+    ^ value
+! !
+
+!AJImmediate methodsFor:'converting'!
+
+asByte
+    "answer the byte representing a value"
+    (self fitsInSize: 1)
+        ifFalse: [ Error signal: self asString, ' exceeds byte (8bit) range' ].
+
+    (self isSigned and: [ value < 0 ]) ifTrue: [ ^ (1<<8) + value ].
+    
+    ^ value
+!
+
+asDWord
+    "answer the 32bit word representing a value"
+    (self fitsInSize: 4)
+        ifFalse: [ Error signal: self asString, ' exceeds doubleword (32bit) range' ].
+
+    (self isSigned and: [ value < 0 ]) ifTrue: [ ^ (1<<32) + value ].
+    
+    ^ value
+!
+
+asQWord
+    "answer the 64bit word representing a value"
+    (self fitsInSize: 8)
+        ifFalse: [ Error signal: self asString, ' exceeds quadword (64bit) range' ].
+
+    (self isSigned and: [ value < 0 ]) ifTrue: [ ^ (1<<64) + value ].
+    
+    ^ value
+!
+
+asWord
+    "answer the 16bit word representing a value"
+    (self fitsInSize: 2)
+        ifFalse: [ Error signal: self asString, ' value exceeds word (16bit) range' ].
+
+    (self isSigned and: [ value < 0 ]) ifTrue: [ ^ (1<<16) + value ].
+    
+    ^ value
+!
+
+ptr
+
+    "turn receiver into a memory operand with absolute address == receiver"
+    
+    ^ AJMem new displacement: self
+! !
+
+!AJImmediate methodsFor:'emitting code'!
+
+emitUsing: emitter size: aSize
+
+    label ifNotNil: [
+        "this will set the label offset"
+        emitter setLabelPosition: label. 
+    ].
+
+    aSize = 1 ifTrue: [ ^ emitter emitByte: self asByte ].
+    aSize = 2 ifTrue: [ ^ emitter emitWord: self asWord ].
+    aSize = 4 ifTrue: [ ^ emitter emitDWord: self asDWord ].
+    aSize = 8 ifTrue: [ ^ emitter emitQWord: self asQWord ].
+    
+    self error: aSize asString, 'bytes is an invalid immediate value size'
+! !
+
+!AJImmediate methodsFor:'initialize-release'!
+
+initialize
+    value := 0.
+    isUnsigned := false.
+! !
+
+!AJImmediate methodsFor:'printing'!
+
+printOn: aStream
+    aStream nextPut: $(.
+
+    self printAnnotationOn: aStream.
+      
+    value > 1000000 
+        ifTrue: [ aStream nextPutAll: value hex]
+        ifFalse: [ aStream print: value].
+
+    aStream space.
+        
+    aStream nextPut: (
+        self isSigned ifTrue: [ $i ] ifFalse: [ $u ]).
+
+    size ifNotNil: [ aStream print: size].
+    
+    aStream nextPut: $).
+
+    
+! !
+
+!AJImmediate methodsFor:'testing'!
+
+fitsInSize: aSize
+    | maxSize |
+    maxSize := 1 << (aSize * 8).
+
+    self isUnsigned 
+        ifTrue: [ ^ maxSize > value ].
+
+    value < 0 
+        ifTrue: [ ^ 0 - value <= (maxSize >> 1) ].
+        
+    ^ value < (maxSize>>1)
+!
+
+isImm
+    ^ true
+!
+
+isInt32
+      ^ value >= -2147483648 and: [ value <= 2147483647 ]
+!
+
+isInt8
+    ^ size ifNil:  [ self fitsInSize: 1 ]
+        ifNotNil: [ size = 1 ]
+!
+
+isSigned 
+    ^ isUnsigned not
+!
+
+isUnsigned 
+    ^ isUnsigned
+!
+
+isZero
+    ^ value = 0
+!
+
+prohibitsRex 
+    "Answer true if use of this operand requires that the instruction *not* have a REX prefix."
+
+    ^ false
+!
+
+requiresRex
+    "Answer true if use of this operand requires that the instruction have a REX prefix."
+
+    ^ false
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJInstruction.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,285 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#AJInstruction
+	instanceVariableNames:'name operands machineCode position next annotation level'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Instructions'
+!
+
+AJInstruction comment:''
+!
+
+!AJInstruction methodsFor:'accessing'!
+
+annotation
+    ^ annotation
+!
+
+annotation: anObject
+    annotation := anObject
+!
+
+extractLabels: aBlock
+
+    operands ifNotNil: [ operands do: [:each | each extractLabels: aBlock ]]
+!
+
+increaseLevel: num
+    level := level + num
+!
+
+insert: anInstructions
+
+    | n |
+    self halt.
+    n := next.
+    next := anInstructions.
+    anInstructions do: [:each | each increaseLevel: level ].
+    anInstructions last next: n
+!
+
+instructionName 
+    ^ name
+!
+
+level
+    ^ level
+!
+
+level: aLevel
+    level := aLevel 
+!
+
+machineCodeSize
+    ^ machineCode ifNil: [ 0 ] ifNotNil: [ machineCode size ]
+!
+
+name
+    ^ name
+        ifNil: ['undefined']
+!
+
+name: anObject
+    name := anObject
+!
+
+next
+    ^ next
+!
+
+next: anObject
+    next := anObject
+!
+
+operands
+    ^ operands
+!
+
+operands: anObject
+    operands := anObject
+!
+
+position
+    ^ position
+!
+
+position: anObject
+    position := anObject
+! !
+
+!AJInstruction methodsFor:'emitting code'!
+
+emitCode: asm
+    machineCode := #[]
+!
+
+emitCodeAtOffset: offset assembler: asm
+
+    position := offset.
+    self emitCode: asm.
+    next ifNotNil: [ next emitCodeAtOffset: offset + self machineCodeSize assembler: asm ].
+! !
+
+!AJInstruction methodsFor:'function calls'!
+
+prepareCallAlignments
+    "do nothing"
+! !
+
+!AJInstruction methodsFor:'helpers'!
+
+checkOperandsForConflict
+    "Subclasses may signal an error here."
+!
+
+find: aByteString 
+    self shouldBeImplemented.
+! !
+
+!AJInstruction methodsFor:'initialize-release'!
+
+initialize
+    level := 0
+! !
+
+!AJInstruction methodsFor:'iterating'!
+
+do: aBlock
+    "evaluate all instructions for the list"
+    | nn |
+    nn := self.
+    [ nn notNil ] whileTrue: [
+        aBlock value: nn.
+        nn := nn next.
+    ].
+!
+
+last
+    "answer the last instruction in the list"
+    | nn l |
+    nn := self.
+    [ (l := nn next) notNil ] whileTrue: [ nn := l ].
+    ^ nn
+! !
+
+!AJInstruction methodsFor:'manipulating'!
+
+insert: newInstruction before: anInstruction
+    
+    "replace a single instruction with one or more other instructions"
+    | instr  anext |
+    
+    anInstruction == self ifTrue: [
+        newInstruction last next: self.
+        ^ newInstruction ].
+    
+    instr := self.
+    [ (anext := instr next) notNil and: [ anext ~~ anInstruction ]] whileTrue: [ instr := anext ].
+
+    instr next ifNotNil: [
+        newInstruction do: [:each | 
+            each increaseLevel: instr level  
+            ].
+        newInstruction last next: instr next.
+        instr next: newInstruction ].  
+!
+
+replace: anInstruction with: otherInstructions
+    
+    "replace a single instruction with one or more other instructions"
+    | instr |
+    
+    anInstruction == self ifTrue: [
+        otherInstructions last next: self next.
+        ^ otherInstructions ].
+    
+    instr := self.
+    [ instr notNil and: [instr next ~~ anInstruction ]] whileTrue: [ instr := instr next ].
+    instr notNil ifTrue: [
+        otherInstructions last next: instr next next.
+        instr next: otherInstructions 
+        ].  
+! !
+
+!AJInstruction methodsFor:'printing'!
+
+printAnnotationOn: aStream 
+    annotation
+        ifNil: [^ self].
+    aStream nextPut: $";
+         nextPutAll: annotation asString;
+         nextPut: $";
+         cr.
+    self printIndentOn: aStream
+!
+
+printIndentOn: aStream 
+    level ifNil: [ ^ self ].
+    level timesRepeat: [ aStream nextPutAll: '|   ']
+!
+
+printListOn: aStream
+    
+    self printIndentOn: aStream.
+    self printSelfOn: aStream.
+    
+    next ifNotNil: [
+        aStream cr.
+        next printListOn: aStream 
+        ]
+!
+
+printMachineCodeOn: aStream 
+    (machineCode isNil
+            or: [machineCode isEmpty])
+        ifTrue: [^ self].
+    aStream padColumn: 65;
+         nextPutAll: '#['.
+    machineCode 
+        do: [ :byte | 
+            byte printOn: aStream base: 16 length: 2 padded: true ]
+        separatedBy: [ aStream space ].
+    aStream nextPut: $]
+!
+
+printOn: aStream  
+"[ ^self ] value."
+
+    self printListOn: aStream asLineStream
+!
+
+printOperandsOn: aStream 
+    (operands notNil
+            and: [operands isEmpty not])
+        ifTrue: [aStream space; nextPut: $(.
+            operands
+                do: [ :operand | operand printAsOperandOn: aStream]
+                separatedBy: [aStream space].
+            aStream nextPut: $)]
+!
+
+printSelfOn: aStream 
+    self printAnnotationOn: aStream.
+    aStream nextPutAll: (self name ). "padRightTo: 4)."
+    self printOperandsOn: aStream.
+    self printMachineCodeOn: aStream
+!
+
+printStringLimitedTo: aNumber
+    ^ String streamContents: [:s | self printOn: s] 
+!
+
+storeOn: aStream
+    "store machine code to binary stream"
+    machineCode ifNotNil: [
+        aStream nextPutAll: machineCode   
+        ]
+! !
+
+!AJInstruction methodsFor:'testing'!
+
+hasLabel
+    self shouldBeImplemented.
+!
+
+isLabelUsed: anAJJumpLabel
+    ^ false
+! !
+
+!AJInstruction methodsFor:'visitor'!
+
+accept: anObject
+    self subclassResponsibility
+!
+
+processTempsWith: anObject
+    "do nothing"
+!
+
+setPrologue: anInstrucitons
+    "do nothing"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJInstructionDecoration.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,47 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJInstructionDecoration
+	instanceVariableNames:'end'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Instructions'
+!
+
+AJInstructionDecoration comment:''
+!
+
+!AJInstructionDecoration methodsFor:'accessing'!
+
+end
+    end := true
+!
+
+start
+    end := false
+! !
+
+!AJInstructionDecoration methodsFor:'printing'!
+
+printIndentOn: aStream 
+    end ifFalse: [ 
+        super printIndentOn: aStream.
+        aStream cr ].
+    ^ super printIndentOn: aStream
+!
+
+printSelfOn: aStream  
+    end 
+        ifFalse: [ aStream nextPutAll: '/ "' ]
+        ifTrue: [	aStream nextPutAll: '\ "end ' ].
+    aStream  nextPutAll: annotation; nextPut: $".
+    
+! !
+
+!AJInstructionDecoration methodsFor:'visitor'!
+
+accept: anObject
+    anObject instructionDecoration: self
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJJumpInstruction.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,61 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJJumpInstruction
+	instanceVariableNames:'label description'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Instructions'
+!
+
+AJJumpInstruction comment:''
+!
+
+!AJJumpInstruction methodsFor:'accessing'!
+
+codeSize
+    ^ machineCode size
+!
+
+description
+    ^ description
+!
+
+description: anInstructionDescription
+    description := anInstructionDescription
+!
+
+label
+    ^ label
+!
+
+label: anObject
+    label := anObject
+! !
+
+!AJJumpInstruction methodsFor:'printing'!
+
+printSelfOn: aStream  
+    aStream nextPutAll: name; space.
+    label printSelfOn: aStream.
+        
+    machineCode ifNotNil: [
+        aStream space; nextPut: $[ .
+        machineCode do: [:byte | aStream nextPutAll: (byte printStringBase: 16)] separatedBy: [ aStream space ].
+        aStream nextPut: $].	
+    ].
+! !
+
+!AJJumpInstruction methodsFor:'testing'!
+
+isLabelUsed: anAJJumpLabel
+    ^ label = anAJJumpLabel 
+! !
+
+!AJJumpInstruction methodsFor:'visitor'!
+
+accept: anObject
+    ^ anObject jumpInstruction: self
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJJumpLabel.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,66 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJJumpLabel
+	instanceVariableNames:'isSet'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Instructions'
+!
+
+AJJumpLabel comment:''
+!
+
+!AJJumpLabel methodsFor:'accessing'!
+
+extractLabels: aBlock
+
+    aBlock value: name value: position
+!
+
+isSet
+    ^ isSet == true
+!
+
+isSet: anObject
+    isSet := anObject
+! !
+
+!AJJumpLabel methodsFor:'emitting code'!
+
+emitCode: asm
+    
+! !
+
+!AJJumpLabel methodsFor:'printing'!
+
+printAsOperandOn: aStream
+    
+    aStream nextPutAll: '@@';
+        nextPutAll: name asString 
+!
+
+printOn: aStream
+    
+    aStream nextPutAll: '@@';
+        nextPutAll: name asString 
+!
+
+printSelfOn: aStream
+    aStream nextPutAll: '@@';
+        nextPutAll: name asString 
+! !
+
+!AJJumpLabel methodsFor:'testing'!
+
+isLabel
+    ^ true
+! !
+
+!AJJumpLabel methodsFor:'visitor'!
+
+accept: anObject
+    anObject jumpLabel: self
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJLineStream.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,68 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#AJLineStream
+	instanceVariableNames:'lineStart writeStream'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Extension'
+!
+
+AJLineStream comment:''
+!
+
+!AJLineStream class methodsFor:'instance creation'!
+
+on: aWriteStream 
+    ^ self new 
+        writeStream: aWriteStream;
+        yourself
+! !
+
+!AJLineStream methodsFor:'error handling'!
+
+doesNotUnderstand: aMessage
+    writeStream 
+        perform: aMessage selector 
+        withArguments: aMessage arguments
+! !
+
+!AJLineStream methodsFor:'writing'!
+
+cr
+    self updateLineStart.
+    writeStream cr
+!
+
+crlf
+    self updateLineStart.
+    writeStream crlf
+!
+
+lf
+    self updateLineStart.
+    writeStream lf
+!
+
+on: aStream 
+    ^ self new 
+        writeStream: aStream;
+        yourself
+!
+
+padColumn: maxCharacterPosition
+    "pad the current line up to maxCharacterPosition with spaces"
+    [writeStream position - lineStart < maxCharacterPosition]
+        whileTrue: [writeStream space]
+!
+
+updateLineStart
+    lineStart := writeStream position
+!
+
+writeStream: aWriteStream 
+    writeStream := aWriteStream.
+    self updateLineStart
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJMMRegister.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,48 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJBaseReg subclass:#AJMMRegister
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-x86-Operands'
+!
+
+AJMMRegister comment:'I am register used for the MMX integer instructions on IA-32 processors.

MMX registers are 64Bit wide, depending on the instructions used the register is used either as 1 x 64bit value, 2 x 32bit values, 4 x 16bit values or 8 x 8bit values.

Note that the MMX register overlap with the floating point register and only use the lower 64bits of the 80bits FPU registers.'
+!
+
+!AJMMRegister methodsFor:'accessing'!
+
+code: aCode
+
+    code := aCode.
+    size := 8.
+!
+
+influencingRegisters
+    "MMX registers overlap with the ST register"
+    self shouldBeImplemented.
+! !
+
+!AJMMRegister methodsFor:'printing'!
+
+descriptionOn: s
+    
+    s nextPutAll: 'An MMX register'.
+! !
+
+!AJMMRegister methodsFor:'testing'!
+
+isGeneralPurpose
+    ^ false
+!
+
+isRegTypeMM
+    ^ true
+!
+
+isX86
+    ^ true
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJMem.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,321 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJOperand subclass:#AJMem
+	instanceVariableNames:'size base index shift segmentPrefix hasLabel target displacement'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Operands'
+!
+
+AJMem comment:'I am memory operand used in assembly instructions. I can be created from an immedate or a register.

Memory operands are used to read values indirectly from memory using certain offsets.

Example:
	asm := AJx86Assembler new.
	
	"create an memory operand on the address 1234"
	1234 asImm ptr
	
	"create a simple memory operand with RAX as base"
	asm RAX ptr.
	
	"the same with a 8 byte offset"
	asm RAX ptr + 8'
+!
+
+!AJMem methodsFor:'accessing'!
+
+* aScale
+    self scale: aScale
+!
+
++ displacementOrIndex
+
+    displacementOrIndex isInteger 
+        ifTrue: [ 
+            self displacement: (AJImmediate new ivalue: displacementOrIndex).
+            ^ self ].
+    
+    displacementOrIndex isGeneralPurpose 
+        ifTrue: [ 
+            index := displacementOrIndex. 
+            ^ self ].
+    
+     self error: 'Expected integer or general purpose register for memory displacement but got ', displacementOrIndex class name, '.'.
+!
+
+- aDisplacement
+
+    aDisplacement isInteger 
+        ifFalse: [ self error: 'Expected integer for memory displacement but got ', aDisplacement class name, '.' ].
+    self displacement: (AJImmediate new ivalue: aDisplacement negated).
+    ^ self
+!
+
+base
+    "Answer the value of base"
+
+    ^ base
+!
+
+base: anObject
+    "Set the value of base"
+
+    base := anObject
+!
+
+displacement
+    "Answer the value of displacement"
+
+    ^ displacement
+!
+
+displacement: anImm
+    "Set the value of displacement"
+    self assert: anImm isImm.
+    displacement := anImm
+!
+
+hasLabel
+    "Answer the value of hasLabel"
+    ^ false
+!
+
+hasLabel: anObject
+    "Set the value of hasLabel"
+
+    hasLabel := anObject
+!
+
+index
+    "Answer the value of index"
+
+    ^ index
+!
+
+index: anIndex
+    "Set the value of index, must be a general purpose register"
+    self assert: (anIndex isGeneralPurpose).
+    index := anIndex
+!
+
+scale: aScale
+    "a valid scale values is 1 , 2 , 4 and 8"
+
+    aScale = 1 ifTrue: [  shift := 0. ^ self ].	
+    aScale = 2 ifTrue: [  shift := 1. ^ self ].	
+    aScale = 4 ifTrue: [  shift := 2. ^ self ].	
+    aScale = 8 ifTrue: [  shift := 3. ^ self ].	
+        
+    self error: 'invalid scale value'
+!
+
+segmentPrefix
+    "Answer the value of segmentPrefix"
+
+    ^ segmentPrefix
+!
+
+segmentPrefix: anObject
+    "Set the value of segmentPrefix"
+
+    segmentPrefix := anObject
+!
+
+shift
+    "Answer the value of shift"
+
+    ^ shift
+!
+
+shift: value
+    "Set the value of shift"
+    self assert: (value >=0 and: [ value < 4 ]).
+    shift := value
+!
+
+size
+
+    ^ size
+!
+
+size: anObject
+    "Set the value of size"
+
+    size := anObject
+! !
+
+!AJMem methodsFor:'emitting'!
+
+emit32BitAbsoluteDisplacementModRM: emitter code: rCode
+    self hasIndex
+        ifTrue: [ 
+            self assert: index index ~= RIDESP.	" ESP/RSP"
+            emitter emitMod: 0 reg: rCode rm: 4.
+            emitter emitScale: shift index: index index base: 5 ]
+        ifFalse: [ emitter emitMod: 0 reg: rCode rm: 5 ].
+        
+    self hasLabel
+        ifTrue: [ 
+            "X86 uses absolute addressing model, all relative addresses will be
+             relocated to absolute ones."
+            "target is label"
+            target
+                addRelocationAt: emitter offset
+                displacement: displacement
+                absolute: true
+                size: 4.
+            emitter emitInt32: 0 ]
+        ifFalse: [ 
+            " Absolute address"
+            displacement emitUsing: emitter size: 4 ]
+!
+
+emitBaseDisplacementModRM: emitter code: rCode
+    | mod |
+    
+    self base isRip
+        ifTrue: [ 
+            emitter emitMod: 0 reg: rCode rm: 2r101.
+            displacement emitUsing: emitter size: 4.
+            ^ self ]. 
+        
+    mod := 0.
+    displacement isZero
+        ifFalse: [ 
+            mod := displacement isInt8 ifTrue: [ 1 ] ifFalse: [ 2 ]].
+        
+    self base index == RIDESP
+        ifTrue: [ 
+            "ESP/RSP/R12"
+            emitter emitMod: mod reg: rCode rm: RIDESP.
+            emitter emitScale: 0 index: RIDESP base: RIDESP ]
+        ifFalse: [ 
+            (self base index ~= RIDEBP and: [ displacement isZero ])
+                ifTrue: [ 
+                    "just base, and not EBP/RBP/R13 "
+                    ^ emitter emitMod: 0 reg: rCode rm: base index ].
+            "force emitting displacement"
+            mod = 0ifTrue: [ mod := 1 ].
+            emitter emitMod: mod reg: rCode rm: base index ].
+            
+    mod = 1 ifTrue: [ displacement emitUsing: emitter size: 1 ].
+    mod = 2 ifTrue: [ displacement emitUsing: emitter size: 4 ].
+!
+
+emitModRM: emitter code: rCode immSize: immSize
+    "Receiver is memory location. rCode is a register number"
+
+    "[base + displacement]"
+    (self hasBase and: [ self hasIndex not ])
+        ifTrue: [ ^ self emitBaseDisplacementModRM: emitter code: rCode ].	
+    
+    "[base + index * scale + displacement]"
+    (self hasBase and: [ self hasIndex ])
+        ifTrue: [ ^ self emitScaledBaseDisplacementModRM: emitter code: rCode ].
+        
+    " Address                       | 32-bit mode | 64-bit mode
+   ------------------------------+-------------+---------------
+   [displacement]                |   ABSOLUTE  | RELATIVE (RIP)
+   [index * scale + displacemnt] |   ABSOLUTE  | ABSOLUTE (ZERO EXTENDED)
+   In 32 bit mode is used absolute addressing model.
+   In 64 bit mode is used relative addressing model together with absolute
+   addressing one. The main problem is that if the instruction contains a SIB byte
+   then relative addressing (RIP) is not possible. "
+    emitter is32BitMode
+        ifTrue: [ ^ self emit32BitAbsoluteDisplacementModRM: emitter code: rCode ].
+            
+    emitter is64BitMode
+        ifTrue: [ self shouldBeImplemented ].
+        
+    self invalidInstruction
+!
+
+emitScaledBaseDisplacementModRM: emitter code: rCode
+
+    self assert: index index ~= RIDESP.
+    (base index ~= RIDEBP and: [ displacement isZero ])
+        ifTrue: [ 
+            emitter emitMod: 0 reg: rCode rm: 4.
+            ^ emitter emitScale: shift index: index index base: base index ].
+        
+    displacement isInt8
+        ifTrue: [ 
+            emitter emitMod: 1 reg: rCode rm: 4.
+            emitter emitScale: shift index: index index base: base index.
+            displacement emitUsing: emitter size: 1 ]
+        ifFalse: [ 
+            emitter emitMod: 2 reg: rCode rm: 4.
+            emitter emitScale: shift index: index index base: base index.
+            displacement emitUsing: emitter size: 4 ].
+    ^ self
+! !
+
+!AJMem methodsFor:'initialize-release'!
+
+initialize
+    displacement := AJImmediate new.
+    shift := 0.
+! !
+
+!AJMem methodsFor:'printing'!
+
+printOn: aStream
+    self printAnnotationOn: aStream.
+    aStream nextPutAll: 'mem['.
+    base
+        ifNotNil: [ 
+            base printAsMemBaseOn: aStream.
+            (index isNil and: [ displacement isNil ])
+                ifFalse: [ aStream nextPutAll: ' + ' ] ].
+    index
+        ifNotNil: [ 
+            aStream nextPutAll: index registerName.
+            self printScaleOn: aStream.
+            displacement ifNotNil: [ aStream nextPutAll: ' + ' ] ].
+    displacement ifNotNil: [ aStream print: displacement ].
+    aStream nextPut: $]
+!
+
+printScaleOn: aStream
+    aStream nextPutAll: ' * '.
+    (2 raisedToInteger: shift) printOn: aStream
+! !
+
+!AJMem methodsFor:'testing'!
+
+hasBase
+    ^ base notNil
+!
+
+hasIndex
+    ^ index notNil
+!
+
+hasSegmentPrefix
+    ^ segmentPrefix notNil
+!
+
+hasUpperBankIndex
+    "True iff I have an index register, and it is one of r8-r15"
+
+    ^ self hasIndex and: [ self index isUpperBank ]
+!
+
+isMem
+    ^ true
+!
+
+isRip
+    ^ self base isRip
+!
+
+isUpperBank
+    "see `AJBaseReg >> #isUpperBank` "
+    ^ self base isUpperBank
+!
+
+prohibitsRex 
+    "Answer true if use of this operand requires that the instruction *not* have a REX prefix."
+
+    ^ false
+!
+
+requiresRex
+    "Answer true if use of this operand requires that the instruction have a REX prefix.
+    For a memory reference, this is true if width of the transfer is 64, 
+    or if either the base or index register is in the upper bank -- the
+    use of a 64-bit base or index register is not enough by itself."
+
+    ^ self is64 or: [ (self hasBase and: [ base isUpperBank ]) or: [ self hasIndex and: [ index isUpperBank ] ] ]
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJOperand.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,252 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#AJOperand
+	instanceVariableNames:'data compilerData operandId x64padding annotation'
+	classVariableNames:''
+	poolDictionaries:'AJConstants'
+	category:'AsmJit-Operands'
+!
+
+AJOperand comment:'I am a generic operand used in the ASMJit assembler.
I define the interface for setting the final instruction code and annotations.'
+!
+
+!AJOperand methodsFor:'accessing'!
+
+annotation
+    ^ annotation
+!
+
+annotation: anObject
+    annotation := anObject
+!
+
+clearId
+    operandId := 0.
+!
+
+compilerData
+    ^ compilerData
+!
+
+operandId
+    ^ operandId
+!
+
+size
+    "Return size of operand in bytes."
+    
+    self shouldBeImplemented 
+!
+
+size16
+    ^ self size: 2
+!
+
+size32
+    ^ self size: 4
+!
+
+size64
+    ^ self size: 8
+!
+
+size8
+    ^ self size: 1
+!
+
+stackSize
+    ^ self size
+! !
+
+!AJOperand methodsFor:'code generation'!
+
+emitPushOnStack: asm
+    asm push: self
+! !
+
+!AJOperand methodsFor:'converting'!
+
+asAJOperand
+    "receiver is already an operand. no nothing"
+!
+
+ptr
+
+    "turn receiver into a memory operand "
+    
+    self subclassResponsibility 
+!
+
+ptr16
+
+    "turn receiver into a memory operand with receiver as base,
+    with 2 bytes size"
+    
+    ^ self ptr size: 2
+!
+
+ptr32
+
+    "turn receiver into a memory operand with receiver as base,
+    with 4 bytes size"
+    
+    ^ self ptr size: 4
+!
+
+ptr64
+
+    "turn receiver into a memory operand with receiver as base,
+    with 8 bytes size"
+    
+    ^ self ptr size: 8
+!
+
+ptr8
+
+    "turn receiver into a memory operand with receiver as base,
+    with 1 byte size"
+    
+    ^ self ptr size: 1
+! !
+
+!AJOperand methodsFor:'labels'!
+
+extractLabels: aBlockClosure
+    " do nothing"
+! !
+
+!AJOperand methodsFor:'printing'!
+
+printAnnotationOn: aStream
+    annotation ifNil: [ ^ self ].
+    aStream 
+        nextPut: $" ; 
+        nextPutAll: annotation asString; 
+        nextPut: $";  space.
+!
+
+printAsOperandOn: aStream
+    self printAnnotationOn: aStream.
+    ^ self printOn: aStream 
+! !
+
+!AJOperand methodsFor:'testing'!
+
+hasUpperBankIndex
+    "True iff I have an index register, and it is one of r8-r15"
+
+    ^ false	"Only can be true for memory references."
+!
+
+is16
+    ^ self size == 2
+!
+
+is32
+    ^ self size == 4
+!
+
+is64
+    ^ self size == 8
+!
+
+is8
+    ^ self size == 1
+!
+
+isImm
+
+    ^ false 
+!
+
+isLabel
+
+    ^ false
+!
+
+isMem
+
+    ^ false
+!
+
+isNone
+    "Return true if operand is none (OP_NONE)."
+    self shouldBeImplemented 
+!
+
+isReg
+
+    ^ false
+!
+
+isRegCode: aRegCode
+
+    self shouldBeImplemented 
+!
+
+isRegIndex: aRegIndex
+
+    ^ self isReg and: [ self index == (aRegIndex bitAnd: RegCodeMask ) ]
+!
+
+isRegMem
+
+    ^ self isReg or: [ self isMem ]
+!
+
+isRegMem: aRegType
+
+    self shouldBeImplemented 
+!
+
+isRegType: aRegType
+
+    ^ self isReg and: [self type == aRegType]
+!
+
+isRegTypeGPB
+    ^ self isRegType: RegGPB
+!
+
+isRegTypeGPD
+    ^ self isRegType: RegGPD
+!
+
+isRegTypeGPQ
+    ^ self isRegType: RegGPQ
+!
+
+isRegTypeGPW
+    ^ self isRegType: RegGPW
+!
+
+isRegTypeMM
+    ^ false
+!
+
+isRegTypeX87
+    ^ false
+!
+
+isRegTypeXMM
+    ^ false
+!
+
+isRip
+    ^ false
+!
+
+prohibitsRex
+    "Answer true if use of this operand requires that the instruction *not* have a REX prefix."
+
+    self subclassResponsibility
+!
+
+requiresRex
+    "Answer true if use of this operand requires that the instruction have a REX prefix."
+
+    self subclassResponsibility
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJRegister.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,47 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJBaseReg subclass:#AJRegister
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Operands'
+!
+
+AJRegister comment:'I am an abstract superclass for the standard x86 registers.'
+!
+
+!AJRegister methodsFor:'accessing'!
+
+code: aCode
+    code := aCode.
+    size :=  1 << (( code bitAnd: RegTypeMask ) >> 4).
+!
+
+influencingRegisters
+    self is8
+        ifFalse: [ ^ self as8 influencingRegisters ].
+    ^ { self as8. self as16. self as32. self as64}
+!
+
+size
+    ^ 1 << (( code bitAnd: RegTypeMask ) >> 4).
+! !
+
+!AJRegister methodsFor:'testing'!
+
+isGeneralPurpose
+    ^ false
+!
+
+isReg
+    ^ true
+!
+
+isX86
+    "Return whether this register is available in the standard x86 instruction set"
+
+    ^ self requiresRex not & (self index < 8)
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJReleaseTemps.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,45 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJReleaseTemps
+	instanceVariableNames:'count'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-StackManagement'
+!
+
+AJReleaseTemps comment:''
+!
+
+!AJReleaseTemps methodsFor:'accessing'!
+
+count
+    ^ count
+!
+
+count: anObject
+    count := anObject
+! !
+
+!AJReleaseTemps methodsFor:'printing'!
+
+printOn: aStream
+    ^ self printSelfOn: aStream  
+!
+
+printSelfOn: aStream
+    aStream nextPutAll: 'Release temps: ';
+    print: count   
+! !
+
+!AJReleaseTemps methodsFor:'visitor'!
+
+accept: anObject
+    anObject visitReleaseTemps: self   
+!
+
+processTempsWith: anObject
+    anObject releaseTemps: count
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJReserveTemp.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,94 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJReserveTemp
+	instanceVariableNames:'operand size'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-StackManagement'
+!
+
+AJReserveTemp comment:'note: assembler should set size even before realizing a temp into stack location reference'
+!
+
+!AJReserveTemp methodsFor:'accessing'!
+
+name
+    ^ name ifNil: [ 'Reserve temp' ]
+!
+
+operand
+    ^ operands first
+!
+
+operand: anObject
+    anObject annotation: annotation.  
+    operands := Array with: anObject 
+!
+
+size
+    ^ size
+!
+
+size: number
+    size := number
+!
+
+stackSize
+    ^ self size
+! !
+
+!AJReserveTemp methodsFor:'converting'!
+
+asAJOperand
+    
+    ^ operands first
+! !
+
+!AJReserveTemp methodsFor:'emitting code'!
+
+emitPushOnStack: asm
+    ^ asm push: self
+! !
+
+!AJReserveTemp methodsFor:'printing'!
+
+printAsOperandOn: aStream
+    
+    annotation ifNotNil: [
+        aStream nextPut: $"; nextPutAll: annotation asString; nextPut: $"; space
+    ].
+
+    operands 
+        ifNil: [ ^ aStream nextPutAll: 'aStackTEMP' ].
+    self operand printAsOperandOn: aStream.
+!
+
+printOn: aStream
+    ^ self printSelfOn: aStream  
+! !
+
+!AJReserveTemp methodsFor:'testing'!
+
+isMem
+    ^ true
+!
+
+prohibitsRex
+"This test is used to validate if operand(s) is valid.. but reserve temp could not have an operand assigned yet and validation 
+can be only performed at instruction analyzis stage (right before emitting the code), but not at instruction creation time"
+    self flag: #todo. 
+    ^ false
+! !
+
+!AJReserveTemp methodsFor:'visitor'!
+
+accept: anObject
+    ^ anObject reserveTemp: self
+!
+
+processTempsWith: anObject
+    anObject reserveTemp: self  
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJRoutineEpilogue.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,14 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJRoutineEpilogue
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Instructions'
+!
+
+AJRoutineEpilogue comment:''
+!
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJRoutinePrologue.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,40 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJRoutinePrologue
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-Instructions'
+!
+
+AJRoutinePrologue comment:'This is a pseudo-instruction to indicate a place in native code for routine prologue.
It is later replaced by real instructions which contain code for initializing stack frame & extra stack space required by routine.'
+!
+
+!AJRoutinePrologue methodsFor:'accessing'!
+
+name
+    ^ 'prologue' 
+! !
+
+!AJRoutinePrologue methodsFor:'emitting code'!
+
+emitCode: asm
+    machineCode := #[]
+! !
+
+!AJRoutinePrologue methodsFor:'visitor'!
+
+accept: anObject
+    ^ anObject visitRoutinePrologue: self
+!
+
+setPrologue: anInstructions
+    "do nothing"
+    | old |
+    old := next.
+    next := anInstructions.
+    anInstructions last next: old 
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJRoutineStackManager.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,125 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#AJRoutineStackManager
+	instanceVariableNames:'calls instructions assembler noStackFrame temps maxTemps
+		extraStackBytes'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-StackManagement'
+!
+
+AJRoutineStackManager comment:''
+!
+
+!AJRoutineStackManager methodsFor:'as yet unclassified'!
+
+analyzeInstructions: anInstructions assembler: asm
+    
+    instructions := anInstructions.
+    assembler := asm.
+    
+    instructions do: #prepareCallAlignments.
+        
+    calls do: [:callInfo |
+        callInfo asm: assembler.
+        callInfo emitAlignmentIfNeeded ].
+
+    instructions do: [:each | each processTempsWith: self].
+
+    self emitPrologue.
+
+    ^ instructions 
+!
+
+emitEpilogue: popExtraBytes assembler: asm
+
+    asm leave.
+    
+    popExtraBytes > 0 ifTrue: [
+        asm ret: popExtraBytes asUImm
+        ]
+    ifFalse: [
+        asm ret.
+        ].
+!
+
+newCdeclCall 
+    self stackFrameCheck.
+    ^ calls add: (AJCdeclCallInfo new)
+!
+
+newStdCall
+    self stackFrameCheck.
+    ^ calls add: (AJStdCallCallInfo new)
+!
+
+noStackFrame
+    noStackFrame := true.
+!
+
+releaseTemps: count
+    temps := temps - count
+!
+
+reserveExtraBytesOnStack: numBytes
+    
+    self stackFrameCheck.
+    
+    extraStackBytes := numBytes 
+!
+
+reserveTemp: anAJReserveTemp
+    self stackFrameCheck.
+    temps := temps + 1.
+    maxTemps := maxTemps max: temps .
+    
+    anAJReserveTemp operand: (assembler stackFrameValueAtOffset: extraStackBytes + (temps * assembler wordSize )).
+!
+
+stackFrameCheck
+
+    noStackFrame ifTrue: [
+        self error: 'Operation requires stack frame management to be enabled for generated code'
+        ].
+! !
+
+!AJRoutineStackManager methodsFor:'emitting'!
+
+emitPrologue
+
+    noStackFrame == true ifTrue: [ ^self ]. 
+    instructions do: [:each |
+        each setPrologue: (assembler instructionsFor: [ | numBytes |
+            assembler 
+                push: assembler EBP;
+                mov: assembler ESP to: assembler EBP.
+                
+            numBytes := extraStackBytes.
+            numBytes := numBytes + (maxTemps * assembler wordSize ).
+             
+            numBytes > 0 ifTrue: [
+                (assembler 
+                    sub: assembler ESP with: numBytes) annotation:
+                        extraStackBytes asString , ' extra bytes + ' ,
+                        maxTemps asString , ' temps'
+                ]			
+            ]).
+        ]
+! !
+
+!AJRoutineStackManager methodsFor:'initialize-release'!
+
+initialize
+    self reset.
+    noStackFrame := false.
+!
+
+reset
+    instructions := nil.
+    assembler := nil.
+    calls := OrderedCollection new.
+    temps := maxTemps := extraStackBytes := 0.
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJStackAlignmentTests.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,69 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+TestCase subclass:#AJStackAlignmentTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:'AJx86Registers'
+	category:'AsmJit-Tests'
+!
+
+AJStackAlignmentTests comment:''
+!
+
+!AJStackAlignmentTests methodsFor:'tests'!
+
+testJumps
+
+    | asm callInfo |
+    
+    asm := self newAssembler.
+    asm noStackFrame.
+    
+    asm jmp: #foo;
+        nop;
+        nop;
+        nop;
+        nop;
+        nop;
+        nop;
+        nop;
+        nop;
+    label: #foo.
+    
+    ^ asm generatedCode.
+!
+
+testNewProtocolForAlignedCalls
+
+    | asm callInfo |
+    
+    asm := self newAssembler.
+    
+    
+    asm cdeclCall:  [:call |
+
+        call 
+            push: EAX;
+            push: EAX;
+            push: 4.
+
+        asm call: EAX.
+        callInfo := call.
+    ] alignment: 32.
+    
+    
+    asm generatedCode. "to analyze instructions"
+    self assert: callInfo stackSize = 12.
+    self assert: callInfo needsAlignment 
+
+    
+! !
+
+!AJStackAlignmentTests methodsFor:'utility'!
+
+newAssembler 
+    ^ AJx86Assembler new
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJStackInstruction.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,26 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJStackInstruction
+	instanceVariableNames:'callInfo'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-StackManagement'
+!
+
+AJStackInstruction comment:''
+!
+
+!AJStackInstruction methodsFor:'accessing'!
+
+callInfo
+
+    ^ callInfo
+!
+
+callInfo: anObject
+
+    callInfo := anObject
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJStdCallCallInfo.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,28 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJCallInfo subclass:#AJStdCallCallInfo
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-StackManagement'
+!
+
+AJStdCallCallInfo comment:'stdcall calling convention.
Used on windows. No need for stack cleanup after call. No need to align stack before making call.'
+!
+
+!AJStdCallCallInfo methodsFor:'emitting code'!
+
+emitAlignment
+    "do nothing"
+    
+    "stdcall calling convention requires no stack alignment, no stack cleanup after call"
+!
+
+emitAlignmentIfNeeded
+    "do nothing"
+    
+    "stdcall calling convention requires no stack alignment, no stack cleanup after call"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx64Assembler.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,400 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJx86Assembler subclass:#AJx64Assembler
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-x86'
+!
+
+AJx64Assembler comment:'I am an assembler for the Intel x86-64 architecture.'
+!
+
+!AJx64Assembler methodsFor:'accessing'!
+
+instructionDesciptions
+    ^ AJx64InstructionDescription instructions
+!
+
+newInstruction
+    ^ AJx64Instruction new
+!
+
+newJumpInstruction
+    ^ AJx64JumpInstruction new
+!
+
+numGPRegisters
+    ^ 16
+!
+
+pointerSize
+    "see AJx86Assembler >> #pointerSize"
+    ^ 8
+! !
+
+!AJx64Assembler methodsFor:'accessing registers'!
+
+BPL
+    ^ BPL
+!
+
+DIL
+    ^ DIL
+!
+
+EIP
+    "A 32bit instruction pointer register
+    This register overlaps with IP, EIP, RIP"
+    ^ EIP
+!
+
+IP
+    "A 16bit instruction pointer register
+    This register overlaps with IP, EIP, RIP"
+    ^ IP
+!
+
+R10
+    "A 64bit general purpose register
+    This register overlaps with R10B, R10W, R10D, R10"
+    ^ R10
+!
+
+R10B
+    "A 8bit general purpose register
+    This register overlaps with R10B, R10W, R10D, R10"
+    ^ R10B
+!
+
+R10D
+    "A 32bit general purpose register
+    This register overlaps with R10B, R10W, R10D, R10"
+    ^ R10D
+!
+
+R10W
+    "A 16bit general purpose register
+    This register overlaps with R10B, R10W, R10D, R10"
+    ^ R10W
+!
+
+R11
+    "A 64bit general purpose register
+    This register overlaps with R11B, R11W, R11D, R11"
+    ^ R11
+!
+
+R11B
+    "A 8bit general purpose register
+    This register overlaps with R11B, R11W, R11D, R11"
+    ^ R11B
+!
+
+R11D
+    "A 32bit general purpose register
+    This register overlaps with R11B, R11W, R11D, R11"
+    ^ R11D
+!
+
+R11W
+    "A 16bit general purpose register
+    This register overlaps with R11B, R11W, R11D, R11"
+    ^ R11W
+!
+
+R12
+    "A 64bit general purpose register
+    This register overlaps with R12B, R12W, R12D, R12"
+    ^ R12
+!
+
+R12B
+    "A 8bit general purpose register
+    This register overlaps with R12B, R12W, R12D, R12"
+    ^ R12B
+!
+
+R12D
+    "A 32bit general purpose register
+    This register overlaps with R12B, R12W, R12D, R12"
+    ^ R12D
+!
+
+R12W
+    "A 16bit general purpose register
+    This register overlaps with R12B, R12W, R12D, R12"
+    ^ R12W
+!
+
+R13
+    "A 64bit general purpose register
+    This register overlaps with R13B, R13W, R13D, R13"
+    ^ R13
+!
+
+R13B
+    "A 8bit general purpose register
+    This register overlaps with R13B, R13W, R13D, R13"
+    ^ R13B
+!
+
+R13D
+    "A 32bit general purpose register
+    This register overlaps with R13B, R13W, R13D, R13"
+    ^ R13D
+!
+
+R13W
+    "A 16bit general purpose register
+    This register overlaps with R13B, R13W, R13D, R13"
+    ^ R13W
+!
+
+R14
+    "A 64bit general purpose register
+    This register overlaps with R14B, R14W, R14D, R14"
+    ^ R14
+!
+
+R14B
+    "A 8bit general purpose register
+    This register overlaps with R14B, R14W, R14D, R14"
+    ^ R14B
+!
+
+R14D
+    "A 32bit general purpose register
+    This register overlaps with R14B, R14W, R14D, R14"
+    ^ R14D
+!
+
+R14W
+    "A 16bit general purpose register
+    This register overlaps with R14B, R14W, R14D, R14"
+    ^ R14W
+!
+
+R15
+    "A 64bit general purpose register
+    This register overlaps with R15B, R15W, R15D, R15"
+    ^ R15
+!
+
+R15B
+    "A 8bit general purpose register
+    This register overlaps with R15B, R15W, R15D, R15"
+    ^ R15B
+!
+
+R15D
+    "A 32bit general purpose register
+    This register overlaps with R15B, R15W, R15D, R15"
+    ^ R15D
+!
+
+R15W
+    "A 16bit general purpose register
+    This register overlaps with R15B, R15W, R15D, R15"
+    ^ R15W
+!
+
+R8
+    "A 64bit general purpose register
+    This register overlaps with R8B, R8W, R8D, R8"
+    ^ R8
+!
+
+R8B
+    "A 8bit general purpose register
+    This register overlaps with R8B, R8W, R8D, R8"
+    ^ R8B
+!
+
+R8D
+    "A 32bit general purpose register
+    This register overlaps with R8B, R8W, R8D, R8"
+    ^ R8D
+!
+
+R8W
+    "A 16bit general purpose register
+    This register overlaps with R8B, R8W, R8D, R8"
+    ^ R8W
+!
+
+R9
+    "A 64bit general purpose register
+    This register overlaps with R9B, R9W, R9D, R9"
+    ^ R9
+!
+
+R9B
+    "A 8bit general purpose register
+    This register overlaps with R9B, R9W, R9D, R9"
+    ^ R9B
+!
+
+R9D
+    "A 32bit general purpose register
+    This register overlaps with R9B, R9W, R9D, R9"
+    ^ R9D
+!
+
+R9W
+    "A 16bit general purpose register
+    This register overlaps with R9B, R9W, R9D, R9"
+    ^ R9W
+!
+
+RAX
+    "A 64bit general purpose register
+    This register overlaps with AL, AX, EAX, RAX"
+    ^ RAX
+!
+
+RBP
+    "A 64bit general purpose register
+    This register overlaps with CH, CX, ECX, RCX"
+    ^ RBP
+!
+
+RBX
+    "A 64bit general purpose register
+    This register overlaps with BL, BX, EBX, RBX"
+    ^ RBX
+!
+
+RCX
+    "A 64bit general purpose register
+    This register overlaps with CL, CX, ECX, RCX"
+    ^ RCX
+!
+
+RDI
+    "A 64bit general purpose register
+    This register overlaps with BH, BX, EBX, RBX"
+    ^ RDI
+!
+
+RDX
+    "A 64bit general purpose register
+    This register overlaps with DL, DX, EDX, RDX"
+    ^ RDX
+!
+
+RIP
+    "A 64bit instruction pointer register
+    This register overlaps with IP, EIP, RIP"
+    ^ RIP
+!
+
+RSI
+    "A 64bit general purpose register
+    This register overlaps with DH, DX, EDX, RDX"
+    ^ RSI
+!
+
+RSP
+    "A 64bit general purpose register
+    This register overlaps with AH, AX, EAX, RAX"
+    ^ RSP
+!
+
+SIL
+    ^ SIL
+!
+
+SPL
+    ^ SPL
+!
+
+XMM10
+    "An SSE register"
+    ^ XMM10
+!
+
+XMM11
+    "An SSE register"
+    ^ XMM11
+!
+
+XMM12
+    "An SSE register"
+    ^ XMM12
+!
+
+XMM13
+    "An SSE register"
+    ^ XMM13
+!
+
+XMM14
+    "An SSE register"
+    ^ XMM14
+!
+
+XMM15
+    "An SSE register"
+    ^ XMM15
+!
+
+XMM8
+    "An SSE register"
+    ^ XMM8
+!
+
+XMM9
+    "An SSE register"
+    ^ XMM9
+! !
+
+!AJx64Assembler methodsFor:'initialize-release'!
+
+initialize
+    super initialize.
+    is64 := true.
+! !
+
+!AJx64Assembler methodsFor:'register'!
+
+accumulator
+    ^ RAX
+!
+
+basePointer
+    ^ RBP 
+!
+
+counter
+    ^ RCX
+!
+
+data
+    ^ RDX
+!
+
+destinationIndex
+    ^ RDI
+!
+
+instructionPointer
+    ^ RIP
+!
+
+sourceIndex
+    ^ RSI
+!
+
+stackPointer
+    ^ RSP
+! !
+
+!AJx64Assembler methodsFor:'testing'!
+
+is32
+    ^ false
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx64AssemblerTests.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,848 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJx86AssemblerTests subclass:#AJx64AssemblerTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:'AJx86Registers'
+	category:'AsmJit-Tests'
+!
+
+AJx64AssemblerTests comment:''
+!
+
+!AJx64AssemblerTests class methodsFor:'as yet unclassified'!
+
+shouldInheritSelectors
+    ^ true
+! !
+
+!AJx64AssemblerTests methodsFor:'tests'!
+
+testAssembly0
+    self assert: [ :a | a mov: 16rfeedface -> RAX ] 
+        bytes: #[72 184 206 250 237 254 0 0 0 0]
+!
+
+testAssembly01
+    self
+        assert: [ :a | 
+            self assert: (a reg: 8 size: 4) = R8D.	"mov    $0xfeedface,%r8d"
+            a mov: 16rfeedface asUImm to: R8D ]
+        bytes: #[65 184 206 250 237 254]
+!
+
+testAssembly1
+
+    
+    self 
+        assert: [ :a|
+            a 
+                push: a RBP;
+                mov: a RSP -> a RBP;
+                mov: 1024 -> a RAX;
+                mov: a RBP -> a RSP;
+                pop: a RBP;
+                ret.]	
+        bytes: #[
+            85 
+            72 139 236 
+            72	199	192	0	4	0	0
+            72 139 229 
+            93 
+            195]
+!
+
+testAssembly2
+
+    self 
+        assert: [ :a|
+        asm 
+            push: a BP;
+            mov: a SP -> a BP;
+            mov: 16r400 -> a RAX;
+            mov: a BP -> a SP;
+            pop: a RSP;
+            ret. ]
+        bytes: #[
+            102 85
+            102 139 236 
+            72	199	192 0 4 0 0
+            102 139 229 
+            92 
+            195]
+    
+!
+
+testAssembly3
+
+    " instructions without operands.
+
+    (AJInstructionDescription instructions select: [:each | each group = #emit]) keys asSortedCollection
+     "
+    | str |
+    str :=
+#(
+#cbw 16r66 16r98
+#cdq 16r99
+#cdqe 16r48 16r98
+#clc 16rF8
+#cld 16rFC
+#cmc 16rF5 
+#cpuid 16r0F 16rA2
+#cqo  16r48	16r99 "64 bit "
+#cwd 16r66 16r99
+#cwde 16r98
+"#daa 16r27 32 bit"
+"#das 16r2F 32 bit"
+#emms 16r0F 16r77
+#f2xm1 16rD9 16rF0
+#fabs  16rD9 16rE1
+#fchs 16rD9 16rE0
+#fclex 16r9B 16rDB 16rE2
+#fcompp 16rDE 16rD9
+#fcos 16rD9 16rFF
+#fdecstp 16rD9 16rF6
+#fincstp 16rD9 16rF7
+#finit 16r9B 16rDB 16rE3
+#fld1 16rD9 16rE8
+#fldl2e 16rD9 16rEA
+#fldl2t 16rD9 16rE9
+#fldlg2 16rD9 16rEC
+#fldln2 16rD9 16rED
+#fldpi 16rD9 16rEB
+#fldz 16rD9 16rEE
+#fnclex 16rDB 16rE2
+#fninit 16rDB 16rE3
+#fnop 16rD9 16rD0
+#fpatan 16rD9 16rF3
+#fprem 16rD9 16rF8
+#fprem1 16rD9 16rF5
+#fptan 16rD9 16rF2
+#frndint 16rD9 16rFC
+#fscale 16rD9 16rFD
+#fsin 16rD9 16rFE
+#fsincos 16rD9 16rFB
+#fsqrt 16rD9 16rFA
+#ftst 16rD9 16rE4
+#fucompp 16rDA 16rE9
+#fwait 16r9B
+#fxam 16rD9 16rE5
+#fxtract  16rD9 16rF4
+#fyl2x  16rD9 16rF1
+#fyl2xp1 16rD9 16rF9
+#int3 16rCC
+#leave  16rC9
+#lfence 16r0F 16rAE 16rE8
+#lock 16rF0 "prefix"
+#mfence 16r0F 16rAE 16rF0
+#monitor 16r0F 16r01 16rC8
+#mwait 16r0F 16r01 16rC9
+#nop 16r90
+#pause 16rF3 16r90
+"#popad 16r61 32 bit"
+#popfd 16r9D
+#popfq 16r48 16r9D   "- 64 bit "
+"#pushad 16r60 32 bit"
+#pushf 16r66 16r9C
+"#pushfd 16r9C 32 bit"
+#pushfq 16r9c" -64 bit"
+#rdtsc 16r0F 16r31  
+#rdtscp 16r0F 16r01 16rF9
+#sahf 16r9E
+#sfence 16r0F 16rAE 16rF8
+#stc 16rF9
+#std 16rFD
+#ud2 16r0F 16r0B
+#std 16rFD "dummy"
+) readStream.
+
+[ str atEnd ] whileFalse: [
+    | instr tst bytes |
+    instr := str next.
+    tst := OrderedCollection new.
+    [ str peek isInteger ] whileTrue: [ tst add: str next  ].
+
+    asm reset noStackFrame.
+    asm perform: instr.
+    bytes := asm bytes.
+    self assert: (bytes = tst asByteArray ) description: instr, ' failed. expected ', tst asByteArray printString, ' but got ', bytes asByteArray printString.
+].
+!
+
+testAssemblyImmAddr
+    "This is not supported in 64-bit mode -- the ModRM value for this results in RIP-relative addressing."
+
+    <expectedFailure>
+    super testAssemblyImmAddr
+!
+
+testAssemblyMemBase
+
+    self 
+        assert: [ :a | a mov: a RAX ptr to: a EAX ]
+        bytes: #[ 16r8B 2r00000000 ].
+        
+    self 
+        assert: [ :a | a mov: a RSP ptr to: a EAX]
+        bytes: #[ 16r8B 16r04 16r24 ].
+    self 
+        assert: [ :a | a mov: a RBP ptr to: a EAX ]
+        bytes: #[ 16r8B 16r45 16r00 ].
+!
+
+testAssemblyMemBaseDisp
+    asm
+        mov: RAX ptr + 1 -> EAX;
+        mov: RBX ptr + ECX -> EAX.
+    self assert: asm bytes = #(16r8B 16r40 16r01 16r8B 16r04 16r0B) asByteArray
+!
+
+testAssemblyMemBaseDisp2
+    asm
+        mov: RAX ptr - 1 -> EAX;
+        mov: (RBX ptr + ECX) * 2 - 5 -> EAX.
+    self assert: asm bytes = #(16r8B 16r40 16rFF 16r8B 16r44 16r4B 16rFB) asByteArray
+!
+
+testAssemblyMemBytes
+    asm
+        mov: (RSI ptr + ECX size: 1) -> BL;
+        mov: BL -> (RSI ptr + ECX size: 1).
+    self assert: asm bytes = #(16r8A 16r1C 16r0E 16r88 16r1C 16r0E) asByteArray
+!
+
+testBitTest
+    "8 Bit ====================================================="
+    self asmShould: [ :a| a bt: a R8B with: 16r1. ] raise: Error.
+    
+    "16 bit ====================================================="
+    "lower bank 16bit register opcode + ModR/M"
+    self 
+        assert: [ :a| a bt: a AX with: 16r01 ]
+        bytes: #[ "16bit mode" 16r66  "OP" 16r0f 16rba "ModRM" 2r11100000 "immediate" 16r01].
+
+    "upper bank 16bit register opcode + ModR/M"
+    self 
+        assert: [ :a| a bt: a R8W with: 16r01 ]
+        bytes: #[ "16bit mode" 16r66 "REX" 2r01000001 "OP" 16r0f 16rba "ModRM" 2r11100000 "immediate" 16r01].
+        
+    "32 bit ====================================================="
+    "lower bank 32bit register opcode + ModR/M"
+    self 
+        assert: [ :a| a bt: a EAX with: 16r01 ]
+        bytes: #[ "OP" 16r0f 16rba "ModRM" 2r11100000 "immediate" 16r01].
+    
+    "upper bank 32bit register opcode + ModR/M"
+    self 
+        assert: [ :a| a bt: a R8D with: 16r01 ]
+        bytes: #[ "REX" 2r01000001 "OP" 16r0f 16rba "ModRM" 2r11100000 "immediate" 16r01].
+    
+    "64 bit ====================================================="
+    "lower bank 32bit register opcode + ModR/M"
+    self 
+        assert: [ :a| a bt: a RAX with: 16r01 ]
+        bytes: #[ "REX" 2r01001000 "OP" 16r0f 16rba "ModRM" 2r11100000 "immediate" 16r01].
+    
+    "upper bank 32bit register opcode + ModR/M"
+    self 
+        assert: [ :a| a bt: a R8 with: 16r01 ]
+        bytes: #[ "REX" 2r01001001 "OP" 16r0f 16rba "ModRM" 2r11100000 "immediate" 16r01].
+!
+
+testByteRegs4through7
+    "Test valid uses of byte registers SPL BPL SIL DIL, only available in 64-bit mode, and when using a REX prefix.
+    Can't be used in the same instruction with AH, CH, DH, or BH -- this is tested in testHighByteRegistersInvalid."
+
+    | byteRegs op2codes opBothCodes mixedWidthOpCodes byteRMOperands wideRegisters |
+    "byteRegs -- register -> contribution to ModRM byte when used as the reg operand"
+    byteRegs := {(SPL -> 16r20).
+    (BPL -> 16r28).
+    (SIL -> 16r30).
+    (DIL -> 16r38)}.	"opBothCodes -- #selector -> #(opcode when byteReg second arg, opcode when byteReg first arg)"
+    opBothCodes := {(#adc:with: -> #(16r10 16r12)).
+    (#add:with: -> #(16r00 16r02)).
+    (#mov:with: -> #(16r88 16r8A)).
+    (#cmp:with: -> #(16r38 16r3A)).
+    (#or:with: -> #(16r08 16r0A)).
+    (#sbb:with: -> #(16r18 16r1A)).
+    (#sub:with -> #(16r28 16r2A)).
+    (#xor:with: -> #(16r30 16r32))}.	"op2Codes -- #selector -> multiByteBytecode. ByteReg is always the second arg"
+    op2codes := {(#cmpxchg:with: -> #[16r0F 16rB0]).
+    (#test:with: -> #[16r84]).
+    (#xadd:with: -> #[16r0F 16rC0])	"xchg is not actually supported at this time (#xchg:with: -> #[16r86])"}.	"mixedWidthOpCodes -- #selector -> multiByteBytecode. ByteReg is always the second arg"
+    mixedWidthOpCodes := {(#movsx:with: -> #[16r0F 16rBE]).
+    (#movzx:with: -> #[16r0F 16rB6])}.	"**** Handle #crc32:with: separately due to its legacy prefix ****"	"wideRegisters -- register -> #[REX prefix, contribution to ModRM byte when used as r/m operand]"
+    wideRegisters := {(EAX -> #[16r40 16rC0]).
+    (RAX -> #[16r48 16rC0]).
+    (R8D -> #[16r44 16rC0]).
+    (R8 -> #[16r4C 16rC0])}.	"byteRMOperands -- operand -> #(REX prefix, #[modRMContribution, SIB and displacement bytes if any])"
+    byteRMOperands := {(SPL -> #(16r40 #[16rC4])).
+    (BPL -> #(16r40 #[16rC5])).
+    (SIL -> #(16r40 #[16rC6])).
+    (DIL -> #(16r40 #[16rC7])).
+    (R8B -> #(16r41 #[16rC0])).
+    (AL -> #(16r40 #[16rC0])).
+    (R8 ptr -> #(16r41 #[16r00])).
+    (RAX ptr -> #(16r40 #[16r00])).
+    (R8 ptr + 16r12 -> #(16r41 #[16r40 16r12])).
+    (RAX ptr + 16r12 -> #(16r40 #[16r40 16r12])).
+    (R8 ptr + 16r1234 -> #(16r41 #[16r80 16r34 16r12 16r00 16r00])).
+    (RAX ptr + 16r1234 -> #(16r40 #[16r80 16r34 16r12 16r00 16r00])).
+    ((RAX ptr + R8) * 2 -> #(16r42 #[16r04 16r40])).
+    ((RAX ptr + RAX) * 2 -> #(16r40 #[16r04 16r40])).
+    ((RAX ptr + R8) * 4 + 16r12 -> #(16r42 #[16r44 16r80 16r12])).
+    ((RAX ptr + RAX) * 4 + 16r12 -> #(16r40 #[16r44 16r80 16r12])).
+    ((RAX ptr + R8) * 8 + 16r1234 -> #(16r42 #[16r84 16rC0 16r34 16r12 16r00 16r00])).
+    ((RAX ptr + RAX) * 8 + 16r1234 -> #(16r40 #[16r84 16rC0 16r34 16r12 16r00 16r00]))}.
+    byteRegs
+        do: [ :reg | 
+            byteRMOperands
+                do: [ :rm | 
+                    opBothCodes
+                        do: [ :opcode | 
+                            | opcodeByte op1 op2 |
+                            op1 := reg key.
+                            op2 := rm key.
+                            opcodeByte := opcode value last.
+                            self
+                                assert: [ :a | a perform: opcode key with: op1 with: op2 ]
+                                bytes:
+                                    (ByteArray with: rm value first with: opcodeByte with: reg value | rm value last first) , rm value last allButFirst	"REX"	"ModRM"	"SIB and displacement"	"Need to add the necessary data to allow testing the reverse order of operands." ].
+                    op2codes
+                        do: [ :opcode | 
+                            self
+                                assert: [ :a | a perform: opcode key with: rm key with: reg key ]
+                                bytes:
+                                    ((ByteArray with: rm value first) , opcode value copyWith: reg value | rm value last first) , rm value last allButFirst	"REX"	"ModRM"	"SIB and displacement" ] ].
+            mixedWidthOpCodes
+                do: [ :opcode | 
+                    wideRegisters
+                        do: [ :rm | 
+                            self
+                                assert: [ :a | a perform: opcode key with: rm key with: reg key ]
+                                bytes: ((ByteArray with: rm value first) , opcode value copyWith: reg value >> 3 | rm value last)	"REX"	"ModRM"	"SIB and displacement" ] ] ]
+!
+
+testCall
+    "relative calls ==================================================================="
+    "8bit offset"
+    self assert: [:a | a call: 16r12 ] bytes: #[ 16rE8 16r12 0 0 0].
+    "16bit offset"
+    self assert: [:a | a call: 16r1234 ] bytes: #[ 16rE8 16r34 16r12 0 0 ].
+    "32bit offset"
+    self assert: [:a | a call: 16r12345678 ] bytes: #[ 16rE8 16r78 16r56 16r34 16r12 ].
+    
+    "indirect calls ==================================================================="
+    "lower bank register"
+    self assert: [:a | a call: asm RAX ] bytes: #[ 16rFF 2r11010000 ].
+    self assert: [:a | a call: asm RDI ] bytes: #[ 16rFF 2r11010111 ].
+    
+    "upper bank register (require REX prefix)"
+    self assert: [:a | a call: asm R8 ] bytes: #[ 2r01001001 16rFF 2r11010000 ].
+    self assert: [:a | a call: asm R15 ] bytes: #[ 2r01001001 16rFF 2r11010111 ].
+    
+    "double indirect calls (with ModR/M) =============================================="
+    "mod = 2r00"
+    "lower bank register"
+    self assert: [:a | a call: a RAX ptr ] bytes: #[ 16rFF 2r00010000 ].
+    self assert: [:a | a call: a RDI ptr ] bytes: #[ 16rFF 2r00010111 ].
+    
+    "upper bank register (require REX prefix)"
+    self assert: [:a | a call: a R8 ptr ] bytes: #[ 2r01000001 16rFF 2r00010000 ].
+    self assert: [:a | a call: a R15 ptr ] bytes: #[ 2r01000001 16rFF 2r00010111 ].
+    
+    "double indirect calls with offsets =============================================="
+    "mod = 2r01 hence with a folllwing 8bit offset"
+    "lower bank register"
+    self assert: [:a | a call: a RAX ptr + 8 ] bytes: #[ 16rFF 2r01010000 8].
+    self assert: [:a | a call: a RDI ptr + 8 ] bytes: #[ 16rFF 2r01010111 8].
+    
+    "upper bank register (require REX prefix)"
+    self assert: [:a | a call: a R8 ptr + 8] bytes: #[ 2r01000001 16rFF 2r01010000 8].
+    self assert: [:a | a call: a R15 ptr + 8] bytes: #[ 2r01000001 16rFF 2r01010111 8].
+    
+    "double indirect calls with offsets =============================================="
+    "mod = 2r10 hence with a following 32bit offset"
+    "lower bank register"
+    self assert: [:a | a call: a RAX ptr + 16r12345678 ] bytes: #[ 16rFF 2r10010000 16r78 16r56 16r34 16r12].
+    self assert: [:a | a call: a RDI ptr + 16r12345678 ] bytes: #[ 16rFF 2r10010111 16r78 16r56 16r34 16r12].
+    
+    "upper bank register (require REX prefix)"
+    self assert: [:a | a call: a R8 ptr + 16r12345678] bytes: #[ 2r01000001 16rFF 2r10010000 16r78 16r56 16r34 16r12].
+    self assert: [:a | a call: a R15 ptr + 16r12345678] bytes: #[ 2r01000001 16rFF 2r10010111 16r78 16r56 16r34 16r12].
+!
+
+testCallInvalid
+    "on 64 bit ..
+    - only 32bit relative offset are allowed
+    - only 64bit registers for indirect addresses"
+
+    "relative calls with 64bit addresses are not supported"
+
+    self asmShould: [ :a | a call: 16r123456789ABCDEF ] raise: Error.
+    AJx86Registers generalPurpose
+        do: [ :register | 
+            register is64
+                ifFalse: [ self asmShould: [ :a | a call: register ] raise: Error ]
+                ifTrue: [ self deny: (self bytes: [ :a | a call: register ]) isEmpty ] ]
+!
+
+testHighByteRegistersInvalid
+    "Can't access AH, BH, CH, DH if a REX byte is required.
+    This test attempts to test every instruction supported by AsmJit that can access an 8-bit general-purpose register AND also require a REX prefix."
+
+    | legacyHRegs op2codes opBothCodes mixedWidthOpCodes byteOperandsRequiringRex wideRegistersRequiringRex |
+    legacyHRegs := {AH.
+    CH.
+    DH.
+    BH}.
+    opBothCodes := #(#adc:with: #add:with: #mov:to: #cmp:with: #or:with: #sbb:with: #sub:with #xchg:with: #xor:with:).
+    op2codes := #(#cmpxchg:with: #test:with: #xadd:with:).
+    mixedWidthOpCodes := #(#crc32:with: #movsx:to: #movzx:to:).
+    wideRegistersRequiringRex := {RAX.
+    R8D}.	"RAX requires REX.W, R8D requires REX.R or REX.B"
+    byteOperandsRequiringRex := {SPL.
+    BPL.
+    SIL.
+    DIL.
+    R8B.
+    (R8 ptr).
+    (R8 ptr + 16r12).
+    (R8 ptr + 16r1234).
+    ((RAX ptr + R8) * 2).
+    ((RAX ptr + R8) * 4 + 16r12).
+    ((RAX ptr + R8) * 8 + 16r1234)}.
+    legacyHRegs
+        do: [ :hreg | 
+            byteOperandsRequiringRex
+                do: [ :operand | 
+                    opBothCodes
+                        do: [ :opcode | 
+                            self asmShould: [ :a | a perform: opcode with: hreg with: operand ] raise: Error.
+                            self asmShould: [ :a | a perform: opcode with: operand with: hreg ] raise: Error ].
+                    op2codes do: [ :opcode | self asmShould: [ :a | a perform: opcode with: operand with: hreg ] raise: Error ] ].
+            mixedWidthOpCodes
+                do: [ :opcode | 
+                    wideRegistersRequiringRex
+                        do: [ :wideReg | self asmShould: [ :a | a perform: opcode with: wideReg with: hreg ] raise: Error ] ] ]
+!
+
+testImmLabels
+    "test immediates with labels"
+
+    | code pos |
+    asm
+        mov: RAX ptr -> EAX;
+        mov: (16rFFFFFFFF asUImm label: (asm labelNamed: #foo)) to: EAX.
+    code := asm generatedCode.
+    pos := code offsetAt: #foo.
+    self assert: (code bytes at: pos + 1) = 255.
+    self assert: (code bytes at: pos + 2) = 255.
+    self assert: (code bytes at: pos + 3) = 255.
+    self assert: (code bytes at: pos + 4) = 255
+!
+
+testIndexScales
+    self
+        assert: [ :a | a mov: RAX -> ((RCX ptr + RDX) * 1) ] bytes: #[16r48 16r89 16r04 16r11];
+        assert: [ :a | a mov: RAX -> ((RCX ptr + RDX) * 2) ] bytes: #[16r48 16r89 16r04 16r51];
+        assert: [ :a | a mov: RAX -> ((RCX ptr + RDX) * 4) ] bytes: #[16r48 16r89 16r04 16r91];
+        assert: [ :a | a mov: RAX -> ((RCX ptr + RDX) * 8) ] bytes: #[16r48 16r89 16r04 16rD1].
+    self
+        assert: [ :a | a mov: (RCX ptr + RDX) * 1 -> RAX ] bytes: #[16r48 16r8B 16r04 16r11];
+        assert: [ :a | a mov: (RCX ptr + RDX) * 2 -> RAX ] bytes: #[16r48 16r8B 16r04 16r51];
+        assert: [ :a | a mov: (RCX ptr + RDX) * 4 -> RAX ] bytes: #[16r48 16r8B 16r04 16r91];
+        assert: [ :a | a mov: (RCX ptr + RDX) * 8 -> RAX ] bytes: #[16r48 16r8B 16r04 16rD1]
+!
+
+testInvalidTest
+    "In 64-bit mode, r/m8 cannot be encoded to access the following byte registers if an REX prefix is used: AH, BH, CH, DH."
+
+    {AH.
+    CH.
+    DH.
+    BH}
+        do: [ :reg | 
+            self deny: (self bytes: [ :a | a test: reg with: AL ]) isEmpty.
+            self deny: (self bytes: [ :a | a test: AL with: reg ]) isEmpty.
+            self deny: (self bytes: [ :a | a test: reg with: 16r12 ]) isEmpty.	"with an upper bank byte register => requires REX prefix"
+            self asmShould: [ :a | a test: reg with: R8B ] raise: Error.
+            self asmShould: [ :a | a test: R8B with: reg ] raise: Error.	"with a 64bit register requring again an REX prefix"
+            self asmShould: [ :a | a test: reg with: RAX ] raise: Error.
+            self asmShould: [ :a | a test: RAX with: reg ] raise: Error ]
+!
+
+testJumps
+
+    self 
+        assert: [:a|
+            a 
+                label: #label1;
+                nop;
+                nop;
+                nop;
+                jz: #label1.
+        ] bytes: #[144 144 144 16r74 251 "-5 asByte"].
+    
+    
+    
+    asm 
+        reset; noStackFrame;
+        label: #label1.
+        126 timesRepeat: [ asm nop ].
+        asm jz: #label1.
+    self assert: (asm bytes size = 128).
+
+
+    self 
+        assert: [:a |
+            a
+                reset; noStackFrame;
+                label: #label1;
+                nop;
+                nop;
+                nop;
+                jmp: #label1.
+        ] bytes: #[144 144 144 235 251 ].
+    
+    self 
+        assert: [:a |
+            a 
+                reset; noStackFrame;
+                jmp: #label1;
+                label: #label1.
+        ] bytes: #[ 16rEB 0 ].
+        
+!
+
+testMovHighIndexRegister
+    "Mov that use r8-r15 as an index register, therefore requiring REX.X"
+
+    self
+        assert: [ :a | a mov: RAX -> ((RCX ptr + R14) * 1) ] bytes: #[16r4A 16r89 16r04 16r31];
+        assert: [ :a | a mov: (RCX ptr + R14) * 1 -> RAX ] bytes: #[16r4A 16r8B 16r04 16r31]
+!
+
+testMovImmediate
+    "8bit immediate to 8bit register"
+    self 
+        assert: [:a | a mov: 16r12 to: a AL ] 
+        bytes: #[16rB0     16r12].
+        
+    "16bit immediate to 16bit register (requires 16bit fallback prefix)"
+    self 
+        assert: [:a | a mov: 16r1234 to: a AX ] 
+        bytes: #[16r66 16rB8     16r34 16r12].
+    
+    "32bit immediate to 32bit register"
+    self 
+        assert: [:a | a mov: 16r12345678 to: a EAX ] 
+        bytes: #[16rB8     16r78 16r56 16r34 16r12].
+    
+    "64bit immediate to 64bit register (requires REX prefix)"
+    self 
+        assert: [:a | a mov: 16r123456789ABCDEF0 to: a RAX ] 
+        bytes: #[2r01001000 16rB8    16rF0 16rDE 16rBC 16r9A 16r78 16r56 16r34 16r12].
+        
+    "32bit immediate sign-extended to 64bit register (REX prefix)"
+    self
+        assert: [:a | a mov: 16r12345678 to: a RAX]
+        bytes: #[ 2r01001000 16rc7 "ModR/M"16rc0    16r78 16r56 16r34 16r12 ]
+!
+
+testMovMemory
+    "mov memory to 8bit register =========================="
+    self 
+        assert: [:a | a mov: a RCX ptr to: a AL ] 
+        bytes: #[16r8A 16r00000001 "ModR/M"].
+    
+!
+
+testMovZX
+    "byte to word ========================================"
+    "lower bank 8bit to lower bank 16bit"
+    self 
+        assert: [:a | a movzx: a AL to: a AX ]
+        bytes: #[102 15 182 192 ].
+    "lower bank 8bit to upper bank 16bit"
+    self 
+        assert: [:a | a movzx: a AL to: a R8W ]
+        bytes: #[102 68 15 182 192].
+    "upper bank 8bit to lower bank 16bit"
+    self 
+        assert: [:a | a movzx: a R8B to: a AX ]
+        bytes: #[102 65 15 182 192].
+    "upper bank 8bit to upper bank 16bit"
+    self 
+        assert: [:a | a movzx: a R8B to: a R8W ]
+        bytes: #[102 69 15 182 192].
+    
+    "byte to doubleword ================================"
+    "lower bank 8bit to lower bank 32bit"
+    self 
+        assert: [:a | a movzx: a AL to: a EAX ]
+        bytes: #[15 182 192 ].
+    "lower bank 8bit to upper bank 32bit"
+    self 
+        assert: [:a | a movzx: a AL to: a R8D ]
+        bytes: #[68 15 182 192].
+    "upper bank 8bit to lower bank 32bit"
+    self 
+        assert: [:a | a movzx: a R8B to: a EAX ]
+        bytes: #[65 15 182 192].
+    "upper bank 8bit to upper bank 32bit"
+    self 
+        assert: [:a | a movzx: a R8B to: a R8D ]
+        bytes: #[69 15 182 192].
+    
+    "byte to quadword ==================="
+    "lower bank 8bit to lower bank 64bit"
+    self 
+        assert: [:a | a movzx: a AL to: a RAX ]
+        bytes: #[72 15 182 192 ].
+    "lower bank 8bit to upper bank 64bit"
+    self 
+        assert: [:a | a movzx: a AL to: a R8 ]
+        bytes: #[76 15 182 192].
+    "upper bank 8bit to lower bank 64bit"
+    self 
+        assert: [:a | a movzx: a R8B to: a RAX ]
+        bytes: #[73 15 182 192 ].
+    "upper bank 8bit to upper bank 64bit"
+    self 
+        assert: [:a | a movzx: a R8B to: a R8 ]
+        bytes: #[77 15 182 192].
+    
+    "word to quadword ==================="
+    "lower bank 16bit to lower bank 64bit"
+    self 
+        assert: [:a | a movzx: a AX to: a RAX ]
+        bytes: #[72 15 183 192].
+    "lower bank 16bit to upper bank 64bit"
+    self 
+        assert: [:a | a movzx: a AX to: a R8 ]
+        bytes: #[76 15 183 192].
+    "upper bank 16bit to lower bank 64bit"
+    self 
+        assert: [:a| a movzx: a R8W to: a RAX ]
+        bytes: #[73 15 183 192].
+    "upper bank 16bit to upper bank 64bit"
+    self 
+        assert: [:a | a movzx: a R8W to: a R8 ]
+        bytes: #[77 15 183 192].
+!
+
+testMovZxSxInvalid
+    {AH.
+    CH.
+    DH.
+    BH}
+        do: [ :reg | 
+            self deny: (self bytes: [ :a | a movzx: reg to: a EAX ]) isEmpty.
+            self asmShould: [ :a | a movzx: reg to: a RAX ] raise: Error ]
+!
+
+testMul
+    "8bit unsigned multiplication =================================="
+    "lower bank register: AX := AL * CL"
+    self 
+        assert: [ :a | a mul: a CL]
+        bytes: #[ 16rF6 "ModR/M" 2r11100001 ].
+    "upper bank register needs an REX prefix: AX := AL * R8B"
+    self 
+        assert: [ :a | a mul: a R9B]
+        bytes: #[ 2r01000001 16rF6 2r11100001].
+        
+    "16bit unsigned multiplication =================================="	
+    "DX:AX := AX * CX"
+    self 
+        assert: [ :a | a mul: a CX]
+        bytes: #[ "16bit fallback" 16r66 16rF7 2r11100001].
+    "32bit unsigned multiplication =================================="	
+    "EDX:EAX := EAX * ECX"
+    self 
+        assert: [ :a | a mul: a ECX]
+        bytes: #[ 16rF7 2r11100001 ].
+    "64bit unsigned multiplication =================================="	
+    "RDX:RAX := RAX * RCX"
+    self 
+        assert: [ :a| a mul: a RCX]
+        bytes: #[ 2r01001000 16rF7 2r11100001].
+!
+
+testNeg
+    "8bit ======================================================"
+    self 
+        assert: [ :a | a neg: a AL]
+        bytes: #[ 16rF6 "ModR/M" 2r11011000 ].
+    "8bit upper bank with REX"
+    self 
+        assert: [ :a | a neg: a R8B]
+        bytes: #[ 2r01000001 16rF6 "ModR/M" 2r11011000 ].
+    
+    "16bit with fallback ======================================="
+    self 
+        assert: [ :a | a neg: a AX]
+        bytes: #[ 16r66 16rF7"ModR/M" 2r11011000 ].
+    "16bit upper bank with REX"
+    self 
+        assert: [ :a | a neg: a R8W]
+        bytes: #[ 16r66 2r01000001 16rF7"ModR/M" 2r11011000 ].
+    "word 16bit IP relative "
+    self 
+        assert: [ :a | a neg: a IP ptr16 + 16r12345678]
+        bytes: #[16r66 16rF7 "ModR/M"2r00011101 16r78 16r56 16r34 16r12].
+        
+    "32bit ===================================================="
+    self 
+        assert: [ :a | a neg: a EAX]
+        bytes: #[ 16rF7"ModR/M" 2r11011000 ].
+    "32bit upper bank with REX"
+    self 
+        assert: [ :a | a neg: a R8D]
+        bytes: #[ 2r01000001 16rF7"ModR/M" 2r11011000 ].
+    "negate double word 32bit EIP relative "
+    self 
+        assert: [ :a | a neg: a EIP ptr32 + 16r12345678]
+        bytes: #[16rF7 "ModR/M"2r00011101 16r78 16r56 16r34 16r12].
+        
+    "64bit with REX =========================================="
+    self 
+        assert: [ :a | a neg: a RAX]
+        bytes: #[ 2r01001000 16rF7 "ModR/M"2r11011000 ].
+    "64bit upper bank"
+    self 
+        assert: [ :a | a neg: a R8]
+        bytes: #[ 2r01001001 16rF7 "ModR/M"2r11011000 ].
+    "negate quadword 64bit RIP relative "
+    self 
+        assert: [ :a | a neg: a RIP ptr64 + 16r12345678]
+        bytes: #["REX"2r01001000 16rF7 "ModR/M"2r00011101 16r78 16r56 16r34 16r12].
+        
+!
+
+testPop
+    "lower bank 64bit register"		
+    self assert: [:a | a pop: a RSP ]
+        bytes: #[ 16r5c ].
+!
+
+testPush
+    "lower bank 64bit register"		
+    self assert: [:a | a push: a RSP ]
+        bytes: #[ 16r54 "16r50 + RSP index" ].
+!
+
+testSyscall
+    self assert: [ :a | a syscall ] bytes: #[16r0F 16r05]
+!
+
+testTest
+    "8bit operand  and lower bank 8bit register"		
+    self assert: [:a | a test: a CL with: 16r12 ]
+        bytes: #[246	 193 16r12].
+    "8bit operand  and uppe bank 8bit register"	
+    self assert: [:a | a test: a R8B with: 16r12]
+        bytes: #[2r01000001 2r11110110  2r11000000  16r12].
+    
+    "16bit operand  and lower bank 16bit register"		
+    self assert: [:a | a test: a CX with: 16r1234]
+        bytes: #[102 247 193   16r34 16r12].
+    "16bit operand  and uppe bank 16bit register"	
+    self assert: [:a | a test: a R8W with: 16r1234]
+        bytes: #[102 65 247 192   16r34 16r12].
+    
+    "32bit operand  and lower bank 32bit register"		
+    self assert: [:a | a test: a ECX with: 16r12345678]
+        bytes: #[247 193   16r78 16r56 16r34 16r12].
+    "32bit operand  and uppe bank 32bit register"	
+    self assert: [:a | a test: a R8D with: 16r12345678]
+        bytes: #[65 247 192   16r78 16r56 16r34 16r12].
+    
+    "32bit operand  and lower bank 64bit register"		
+    self assert: [:a| a test: a RCX with: 16r12345678]
+        bytes: #[72 247 193   16r78 16r56 16r34 16r12].
+    "32bit operand  and uppe bank 64bit register"	
+    self assert: [:a| a test: a R8 with: 16r12345678]
+        bytes: #[73 247 192	  16r78 16r56 16r34 16r12].
+    
+    
+    
+!
+
+testXor
+    "8bit register xor 8bit immediate =================================="		
+    "lower bank 8bit register opcode + ModR/M"
+    self 
+        assert: [ :a | a xor: a CL with: 16r12]
+        bytes: #[ 16r80 2r11110001    16r12].
+        
+    "upper bank 8bit register requiring REX"
+    self 
+        assert: [ :a | a xor: a R8B with: 16r12]
+        bytes: #[2r01000001 16r80 2r11110000    16r12].
+        
+    "16bit register xor 8bit immediate =================================="
+    "lower bank 16bit register"
+    self 
+        assert: [ :a | a xor: a CX with: 16r1234]
+        bytes: #[16r66 16r81 2r11110001    16r34 16r12].
+    "upper bank 16bit"
+    self 
+        assert: [ :a | a xor: a R8W with: 16r1234]
+        bytes: #[16r66 2r01000001 16r81 2r11110000 16r34 16r12].
+        
+    "32bit register ====================================================="
+    "lower bank 32bit register"
+    self 
+        assert: [ :a | a xor: a ECX with: 16r12345678]
+        bytes: #[16r81 2r11110001    16r78 16r56 16r34 16r12].
+        
+    "upper bank register requiring REX prefix"
+    self 
+        assert: [ :a | a xor: a R8D with: 16r12345678]
+        bytes: #[2r01000001 16r81 2r11110000     16r78 16r56 16r34 16r12]
+    
+!
+
+testXorFastCode
+    self  "shortcut for AL + 8bit immedidate"
+        assert: [ :a | a xor: a AL with: 16r12]
+        bytes: #[ 16r34    16r12].
+        
+    self  "shortcut for AX + 16bit immedidate"
+        assert: [ :a | a xor: a AX with: 16r1234]
+        bytes: #[ 16r66 16r35    16r34 16r12].
+        
+    self  "shortcut for EAX + 16bit immedidate"
+        assert: [ :a | a xor: a EAX with: 16r12345678]
+        bytes: #[ 16r35    16r78 16r56 16r34 16r12].
+        
+    self  "shortcut for RAX + 32bit immedidate"
+        assert: [ :a | a xor: a RAX with: 16r12345678]
+        bytes: #[ 2r01001000 16r35    16r78 16r56 16r34 16r12].
+!
+
+testXorInvalid
+    "xor registers with non-matching sizes"
+
+    self asmShould: [ :a | a xor: AL to: RAX ] raise: Error.
+    self asmShould: [ :a | a xor: RAX to: AL ] raise: Error.
+    self asmShould: [ :a | a xor: R8B to: RAX ] raise: Error.
+    self asmShould: [ :a | a xor: RAX to: R8B ] raise: Error.	"in 64bit mode AH CH DH and BH cannot be encoded when an REX prefix is present"
+    {AH.
+    CH.
+    DH.
+    BH} do: [ :reg | self asmShould: [ :a | a xor: reg to: a R8B ] raise: Error ]
+! !
+
+!AJx64AssemblerTests methodsFor:'utility'!
+
+newAssembler 
+    ^ AJx64Assembler new
+        noStackFrame;
+        yourself
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx64Instruction.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,41 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJx86Instruction subclass:#AJx64Instruction
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-x86-Instructions'
+!
+
+AJx64Instruction comment:''
+!
+
+!AJx64Instruction methodsFor:'accessing'!
+
+instructionDesciptions
+    ^ AJx64InstructionDescription instructions
+! !
+
+!AJx64Instruction methodsFor:'testing'!
+
+is32BitMode
+    ^ false
+!
+
+is64BitMode
+    ^ true
+!
+
+requiresRex
+    "Answer true if I absolutely must have a REX prefix."
+
+    ^ (operands
+        detect: [ :rawOp | 
+            | op |
+            op := rawOp asAJOperand.
+            op requiresRex | op is64 ]
+        ifNone: [ #none ]) ~~ #none
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx64InstructionDescription.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,239 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJx86InstructionDescription subclass:#AJx64InstructionDescription
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-x86-Instructions'
+!
+
+AJx64InstructionDescription comment:''
+!
+
+!AJx64InstructionDescription methodsFor:'code emitting'!
+
+emitalu: emitter operand1: op1 operand2: op2 operand3: op3
+    | opCode opReg |
+    opCode := opCode1.
+    opReg := opCodeR.	" Mem <- Reg "
+    (op1 isMem and: [ op2 isReg ])
+        ifTrue: [ 
+            ^ emitter
+                emitX86RM: opCode + op2 isRegTypeGPB not asBit
+                size: op2 size
+                regOrCode: op2
+                rm: op1 ].	"Reg <- Reg|Mem"
+    (op1 isReg and: [ op2 isRegMem ])
+        ifTrue: [ 
+            (op2 isReg and: [ op1 size ~= op2 size ])
+                ifTrue: [ self invalidInstruction ].
+            ^ emitter
+                emitX86RM: opCode + 2 + op1 isRegTypeGPB not asBit
+                size: op1 size
+                regOrCode: op1
+                rm: op2 ].
+    op2 isImm
+        ifFalse: [ self invalidInstruction ].	" AL, AX, EAX, RAX register shortcuts"
+    (op1 isRegIndex: 0)
+        ifTrue: [ 
+            op1 is16
+                ifTrue: [ emitter emitByte: 16r66	" 16 bit " ].
+            op1 is64
+                ifTrue: [ emitter emitByte: 16r48	" REX.W" ].
+            emitter emitByte: (opReg << 3 bitOr: 16r04 + op1 isRegTypeGPB not asBit).
+            ^ emitter emitImmediate: op2 size: (op1 size min: 4) ].	"short constant"
+    op2 isInt8
+        ifTrue: [ 
+            | szBits |
+            szBits := op1 size = 1
+                ifTrue: [ 0 ]
+                ifFalse: [ 3 ].
+            emitter
+                emitX86RM: opCode2 + szBits
+                size: op1 size
+                regOrCode: opReg
+                rm: op1
+                immSize: 1.
+            ^ emitter emitImmediate: op2 size: 1 ].
+    op1 isRegMem
+        ifTrue: [ 
+            | immSize szBits |
+            immSize := op2 isInt8
+                ifTrue: [ 1 ]
+                ifFalse: [ op1 size min: 4 ].
+            szBits := op1 size ~= 1
+                ifTrue: [ 
+                    immSize ~= 1
+                        ifTrue: [ 1 ]
+                        ifFalse: [ 3 ] ]
+                ifFalse: [ 0 ].
+            emitter
+                emitX86RM: opCode2 + szBits
+                size: op1 size
+                regOrCode: opReg
+                rm: op1
+                immSize: immSize.
+            ^ emitter emitImmediate: op2 size: immSize ].
+    self invalidInstruction
+!
+
+emitbswap: emitter operand1: op1 operand2: op2 operand3: op3
+
+    op1 isReg ifTrue: [
+        emitter emitRexForSingleOperand: op1.
+        emitter emitByte: 16r0F.
+        ^ emitter emitModR: 1 r: op1 code
+    ].
+    self invalidInstruction.
+!
+
+emitcall: emitter operand1: op1 operand2: op2 operand3: op3
+
+    (op1 isReg and: [ op1 is64 and: [ op1 isUpperBank not ]]) ifTrue: [ 
+        "shortcut"
+        emitter emitByte: 16rFF. 
+        op1 emitModRM: emitter code: 2 immSize: 4.
+        ^ self].
+    
+    (op1 isMem and: [op1 hasBase and: [ op1 base is64 and: [ op1 base isUpperBank not ]]]) ifTrue: [ 
+        "shortcut"
+        emitter emitByte: 16rFF. 
+        op1 emitModRM: emitter code: 2 immSize: 4.
+        ^ self].
+    
+    (op1 isMem or: [ op1 isReg and: [ op1 is64 ] ]) ifTrue: [
+        ^ emitter emitX86RM:  16rFF
+            size: 4
+            regOrCode: 2  
+            rm: op1  
+    ].
+
+    op1 isImm ifTrue: [ "call by relative offset, you should be really sure what you're' doing"
+        emitter emitByte: 16rE8. 
+        op1 emitUsing: emitter size: 4.
+        ^ self.
+        ].
+    
+    op1 isLabel ifTrue: [
+        emitter emitByte: 16rE8. 
+        emitter emitDisplacement: op1 inlinedDisp: -4.
+        ^ self
+    ].
+    self invalidInstruction.
+!
+
+emitmov: emitter operand1: dst operand2: src operand3: op3
+    
+    src isReg & dst isReg ifTrue: [
+        self assert: (src isRegTypeGPB | src isRegTypeGPW | src isRegTypeGPD | src isRegTypeGPQ ).
+        ]. 
+    
+    " reg <- mem "
+    dst isReg & src isRegMem ifTrue: [
+        self assert: (dst isRegTypeGPB | dst isRegTypeGPW | dst isRegTypeGPD | dst isRegTypeGPQ ).
+        src isMem
+            ifTrue: [ (src base notNil and: [ src base is64 not ])
+                ifTrue: [ Error signal: 'use a 64bit base register instead of ', src base asString, '(', (src base size * 8) asString, 'bit) for memory access on a 64bit CPU' ]]
+            ifFalse:[ (src size = dst size) 
+                ifFalse: [ Error signal: 'source ',src asString,' and destination ',dst asString,' need to have the same size' ]].
+        ^ emitter emitX86RM: 16r0000008A + dst isRegTypeGPB not asBit 
+            size:  dst size 
+            regOrCode:  dst 
+            rm: src
+        ].
+
+    " reg <- imm "
+    dst isReg & src isImm ifTrue: [
+        | immSize |
+        immSize := dst size.
+        "Optimize instruction size by using 32 bit immediate if value can fit to it"
+        emitter is64BitMode & immSize = 8 & src isInt32 & (src relocMode == #RelocNone) ifTrue: [
+             emitter emitX86RM: 16rC7
+                size: dst size
+                regOrCode: 0 rm: dst.
+            immSize := 4
+        ] ifFalse: [
+            emitter emitX86Inl: (immSize=1 ifTrue: [16rB0] ifFalse: [16rB8]) reg: dst.
+        ].
+        ^ emitter emitImmediate: src size: immSize
+    ].
+
+    "mem <- reg"
+    dst isMem & src isReg ifTrue: [
+        self assert: (src isRegTypeGPB | src isRegTypeGPW | src isRegTypeGPD | src isRegTypeGPQ ).
+        ^ emitter emitX86RM: 16r88 + src isRegTypeGPB not asBit
+            size: src size regOrCode: src rm: dst
+    ].
+
+    "mem <- imm"
+    dst isMem & src isImm ifTrue: [ | immSize |
+        
+        immSize := dst size <= 4 ifTrue: [ dst size ] ifFalse: [4].
+        
+        emitter emitX86RM: 16rC6 + ((dst size = 1) not) asBit
+            size: dst size 
+            regOrCode:  0 rm:  dst 
+            immSize: immSize.
+        
+        ^ emitter emitImmediate: src size: immSize
+    ].
+
+    self invalidInstruction 
+!
+
+emitmovPtr: emitter operand1: op1 operand2: op2 operand3: op3
+
+    | reg imm opCode |
+    (op1 isReg & op2 isImm) | (op1 isImm & op2 isReg) ifFalse: [
+        self invalidInstruction ].
+    
+    opCode := op1 isReg 
+        ifTrue: [reg := op1. imm := op2. 16rA0] 
+        ifFalse: [reg := op2. imm := op1. 16rA2].
+    
+    reg index ~= 0 ifTrue: [ self invalidInstruction ].
+
+    reg isRegTypeGPW ifTrue: [ emitter emitByte: 16r66 ].
+
+    emitter emitRexForSingleOperand: reg.
+    emitter emitByte: opCode + (reg size ~=1) asBit.
+    emitter emitImmediate: imm size: reg size
+!
+
+emitmovSxZx: emitter operand1: dst operand2: src operand3: op3
+    dst isReg & src isRegMem
+        ifFalse: [ self invalidInstruction ].
+    src size >= dst size
+        ifTrue: [ self invalidInstruction ].
+    dst isGeneralPurpose
+        ifFalse: [ self invalidInstruction ].
+    src is16
+        ifTrue: [ 
+            ^ emitter
+                emitX86RM: opCode1 + 1
+                size: dst size
+                regOrCode: dst
+                rm: src ].
+    src is32
+        ifTrue: [ self invalidInstruction ].	"64 bit source"
+    emitter
+        emitX86RM: opCode1
+        size: dst size
+        regOrCode: dst
+        rm: src
+!
+
+emitpop: emitter operand1: op1 operand2: op2 operand3: op3
+    op1 isReg ifTrue: [
+        self assert: op1 isGeneralPurpose.
+        (op1 is32 or: [ op1 is8 ]) 
+            ifTrue: [ Error signal: 'invalid register ', op1 name, '. push/pop requires 64bit/16bit reg in 64bit mode'].
+        ^ emitter emitX86Inl: opCode1 reg: op1 withRex: op1 isUpperBank.
+        ].
+    
+    op1 isMem ifFalse: [ self invalidInstruction ].
+    emitter emitX86RM: opCode2 size: op1 size regOrCode: opCodeR rm: op1
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx64JumpInstruction.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,20 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJx86JumpInstruction subclass:#AJx64JumpInstruction
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-x86-Instructions'
+!
+
+AJx64JumpInstruction comment:''
+!
+
+!AJx64JumpInstruction methodsFor:'accessing'!
+
+instructionDesciptions
+    ^ AJx64InstructionDescription instructions
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx64RipRegister.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,79 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJx86GPRegister subclass:#AJx64RipRegister
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:'AJx86Registers'
+	category:'AsmJit-x86-Operands'
+!
+
+AJx64RipRegister comment:'Virtual registers used for relative instruction pointer addressing in 64Bit mode

In IA-32 architecture and compatibility mode, addressing relative to the instruction pointer is available only with control-transfer instructions. In 64-bit mode, instruc- tions that use ModR/M addressing can use RIP-relative addressing. Without RIP-rela- tive addressing, all ModR/M instruction modes address memory relative to zero.'
+!
+
+!AJx64RipRegister methodsFor:'accessing'!
+
+code
+    self ripAccessError
+!
+
+index
+    self ripAccessError
+!
+
+influencingRegisters
+    self is16
+        ifFalse: [ ^ self as16 influencingRegisters ].
+    ^ { self as16. self as32. self as64 }
+! !
+
+!AJx64RipRegister methodsFor:'converting'!
+
+as16
+    ^ AJx86Registers at: #IP
+!
+
+as32
+    ^ AJx86Registers at: #EIP
+!
+
+as64
+    ^ AJx86Registers at: #RIP
+!
+
+as8
+    
+    self error: 'No 8bit register available for instruction pointer relative addressing'
+! !
+
+!AJx64RipRegister methodsFor:'error'!
+
+ripAccessError
+    self error: 'RIP register ', self name, ' cannot be used only for relative addressing'
+! !
+
+!AJx64RipRegister methodsFor:'printing'!
+
+descriptionOn: s
+    s nextPutAll: 'A '; print: self size * 8; nextPutAll: 'bit instruction pointer register'.
+! !
+
+!AJx64RipRegister methodsFor:'testing'!
+
+isGeneralPurpose
+    ^ false
+!
+
+isRip
+    ^ true
+!
+
+isUpperBank
+    ^ false
+!
+
+isX86 
+    ^ false
+! !
+
Binary file asm/AJx86Assembler.st has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx86AssemblerTests.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,467 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+TestCase subclass:#AJx86AssemblerTests
+	instanceVariableNames:'asm'
+	classVariableNames:''
+	poolDictionaries:'AJx86Registers'
+	category:'AsmJit-Tests'
+!
+
+AJx86AssemblerTests comment:''
+!
+
+!AJx86AssemblerTests methodsFor:'running'!
+
+setUp
+    super setUp.
+    asm := self newAssembler.
+! !
+
+!AJx86AssemblerTests methodsFor:'tests'!
+
+testAssembly1
+    
+    asm 
+        push: EBP;
+        mov: ESP -> EBP;
+        mov: 1024 -> EAX;
+        mov: EBP -> ESP;
+        pop: EBP;
+        ret.
+    
+    self assert: asm bytes = #(85 139 236 184 0 4 0 0 139 229 93 195) asByteArray
+!
+
+testAssembly3
+
+    " instructions without operands.
+
+    (AJInstructionDescription instructions select: [:each | each group = #emit]) keys asSortedCollection
+     "
+    | str |
+    str :=
+#(
+#cbw 16r66 16r98
+#cdq 16r99
+"#cdqe  64 bit "
+#clc 16rF8
+#cld 16rFC
+#cmc 16rF5 
+#cpuid 16r0F 16rA2
+"#cqo  64 bit "
+#cwd 16r66 16r99
+#cwde 16r98
+#daa 16r27
+#das 16r2F
+#emms 16r0F 16r77
+#f2xm1 16rD9 16rF0
+#fabs  16rD9 16rE1
+#fchs 16rD9 16rE0
+#fclex 16r9B 16rDB 16rE2
+#fcompp 16rDE 16rD9
+#fcos 16rD9 16rFF
+#fdecstp 16rD9 16rF6
+#fincstp 16rD9 16rF7
+#finit 16r9B 16rDB 16rE3
+#fld1 16rD9 16rE8
+#fldl2e 16rD9 16rEA
+#fldl2t 16rD9 16rE9
+#fldlg2 16rD9 16rEC
+#fldln2 16rD9 16rED
+#fldpi 16rD9 16rEB
+#fldz 16rD9 16rEE
+#fnclex 16rDB 16rE2
+#fninit 16rDB 16rE3
+#fnop 16rD9 16rD0
+#fpatan 16rD9 16rF3
+#fprem 16rD9 16rF8
+#fprem1 16rD9 16rF5
+#fptan 16rD9 16rF2
+#frndint 16rD9 16rFC
+#fscale 16rD9 16rFD
+#fsin 16rD9 16rFE
+#fsincos 16rD9 16rFB
+#fsqrt 16rD9 16rFA
+#ftst 16rD9 16rE4
+#fucompp 16rDA 16rE9
+#fwait 16r9B
+#fxam 16rD9 16rE5
+#fxtract  16rD9 16rF4
+#fyl2x  16rD9 16rF1
+#fyl2xp1 16rD9 16rF9
+#int3 16rCC
+#leave  16rC9
+#lfence 16r0F 16rAE 16rE8
+#lock 16rF0 "prefix"
+#mfence 16r0F 16rAE 16rF0
+#monitor 16r0F 16r01 16rC8
+#mwait 16r0F 16r01 16rC9
+#nop 16r90
+#pause 16rF3 16r90
+#popad 16r61
+#popfd 16r9D
+" #popfq 16r48 16r9D   - 64 bit "
+#pushad 16r60
+#pushf 16r66 16r9C
+#pushfd 16r9C
+" #pushfq -64 bit"
+#rdtsc 16r0F 16r31  
+#rdtscp 16r0F 16r01 16rF9
+#sahf 16r9E
+#sfence 16r0F 16rAE 16rF8
+#stc 16rF9
+#std 16rFD
+#ud2 16r0F 16r0B
+#std 16rFD "dummy"
+) readStream.
+
+[ str atEnd ] whileFalse: [
+    | instr tst |
+    instr := str next.
+    tst := OrderedCollection new.
+    [ str peek isInteger ] whileTrue: [ tst add: str next  ].
+
+    asm reset noStackFrame.
+    asm perform: instr.
+    self assert: (asm bytes = tst asByteArray )
+].
+!
+
+testAssemblyImmAddr
+    "test generating immediate address, 
+    note GDB disassembling it to:
+        0x1fab <instructions.1862>:     0x8b    0x05    0xef    0xbe    0xad    0xde
+        0x00001fab <instructions.1862+0>:       mov    0xdeadbeef,%eax
+    which is WRONG!!
+    "
+
+    asm
+        mov: 16rdeadbeef asUImm ptr32 to: asm EAX. 
+
+    " 8b05efbeadde                   mov         eax, [deadbeef] "
+    
+    self assert: asm bytes =  #[139 5 239 190 173 222]
+    
+!
+
+testAssemblyMemBase
+    
+    asm 
+        mov: EAX ptr  -> EAX;
+        mov: ESP ptr -> EAX;
+        mov: EBP ptr -> EAX.
+    
+    self assert: asm bytes = #(16r8B 0 16r8B 16r04 16r24 16r8B 16r45 16r00) asByteArray
+!
+
+testAssemblyMemBaseDisp
+
+    asm 
+        mov: EAX ptr + 1 -> EAX;
+        mov: EBX ptr + ECX -> EAX.
+    
+    self assert: asm bytes = #(16r8B 16r40 16r01 16r8B 16r04 16r0B) asByteArray
+!
+
+testAssemblyMemBaseDisp2
+
+    asm 
+        mov: EAX ptr - 1 -> EAX;
+        mov: EBX ptr + ECX * 2 - 5 -> EAX.
+    
+    self assert: asm bytes = #(16r8B 16r40 16rFF 16r8B 16r44 16r4B 16rFB) asByteArray
+!
+
+testAssemblyMemBytes
+
+    asm 
+        mov: ((ESI ptr + ECX) size: 1) -> BL;
+        mov: BL -> ((ESI ptr + ECX) size:1).
+        
+    self assert: asm bytes = #(16r8A 16r1C 16r0E 16r88 16r1C 16r0E ) asByteArray
+!
+
+testBitTest
+
+    asm 
+        bt: EAX with: 0.
+
+    self assert: asm bytes =  #(16r0F 16rBA 16rE0 16r00) asByteArray
+!
+
+testCall
+
+    asm 
+        call: EAX;
+        call: EAX ptr - 4;
+        call: EAX ptr.
+    self assert: asm bytes =  #(255 208 255 80 252 255 16) asByteArray
+!
+
+testForwardJumps
+    
+    asm
+        jmp: #label1;
+        label: #label1.
+
+    self assert: asm bytes =  #(16rEB 0 ) asByteArray.
+        
+!
+
+testImmLabels
+
+    "test immediates with labels"
+    
+    | code pos |
+    
+    asm 
+        mov: EAX ptr  -> EAX;
+        mov: (16rFFFFFFFF asUImm label: (asm labelNamed: #foo) ) to:  EAX.
+    
+    code := asm generatedCode.
+    pos := code offsetAt: #foo.
+
+    self assert: (code bytes at: pos+1) = 255.
+    self assert: (code bytes at: pos+2) = 255.
+    self assert: (code bytes at: pos+3) = 255.
+    self assert: (code bytes at: pos+4) = 255.
+!
+
+testJMPRegister
+    
+    self 
+        assert: [  :assembler |
+            assembler jmp: assembler EAX ]
+        bytes: #[ 16rFF 2r11100000 ].
+        
+    self 
+        assert: [  :assembler |
+            assembler jmp: assembler ECX ]
+        bytes: #[ 16rFF 2r11100001 ].
+        
+    self 
+        assert: [  :assembler |
+            assembler jmp: assembler EDX ]
+        bytes: #[ 16rFF 2r11100010 ]
+!
+
+testJumps
+    
+    asm 
+        label: #label1;
+        nop;
+        nop;
+        nop;
+        jz: #label1.
+        
+    self assert: asm bytes =  #(144 144 144 116 251) asByteArray.
+
+    
+    asm 
+        reset; noStackFrame;
+        label: #label1.
+        126 timesRepeat: [ asm nop ].
+        asm jz: #label1.
+    self assert: (asm bytes size = 128).
+    
+    asm 
+        reset; noStackFrame;
+        label: #label1;
+        nop;
+        nop;
+        nop;
+        jmp: #label1.
+        
+    self assert: asm bytes =  #(144 144 144 235 251) asByteArray.
+    
+    asm
+        reset; noStackFrame;
+        jmp: #label1;
+        label: #label1.
+        
+    self assert: asm bytes =  #(16rEB 0 ) asByteArray.
+        
+!
+
+testMovSxZx
+
+    asm 
+        movsx: asm AX to: asm EAX;
+        movzx: asm AX to: asm EAX;
+        movsx: asm AL to: asm EAX;
+        movzx: asm AH to: asm EAX.
+
+    self assert: asm bytes = 
+    #[
+        16r0F 16rBF 16rC0
+        16r0F 16rB7 16rC0
+        16r0F 16rBE 16rC0
+        16r0F 16rB6 16rC4 ]
+!
+
+testRegistersOf: asm
+
+    | numRegs |
+    numRegs := asm numGPRegisters.
+    
+    0 to: numRegs-1 do: [:i |
+        self assert: (asm reg8: i) size = 1.
+        self assert: (asm reg8: i) index = i.
+        
+        self assert: (asm reg16: i) size = 2.
+        self assert: (asm reg16: i) index = i.
+        
+        self assert: (asm reg32: i) size = 4.
+        self assert: (asm reg32: i) index = i.
+
+        self assert: (asm isGPNRegister: (asm nReg: i)).
+    
+        asm is64BitMode ifTrue: [
+            self assert: (asm reg64: i) size = 8.
+            self assert: (asm reg64: i) index = i.
+            ]	
+    ].
+    
+!
+
+testSyscall
+    "Syscall instruction is only valid in 64-bit mode"
+
+    self asmShould: [ :a | a syscall ] raise: Error
+!
+
+testTest
+    "Special RAX opcodes"
+    
+    "8bit operand  opcode"		
+    asm 
+        test: AL with: 5.
+    self assert: asm bytes = #[16rA8 05].
+
+    
+    asm reset;
+        test: AX with: 5.
+    "16bit operand Prefix byte, 16bit immediate (LSB)"
+    self assert: asm bytes = #[16r66 16rA9 05 0].
+
+    "32bit operand "
+    asm reset;
+        test: EAX with: 1.
+    self assert: asm bytes =  #[16rA9 01 00 00 00].
+    
+    "Need more assert for non-EAX receiver, non-immediate operands"
+    
+    
+    
+! !
+
+!AJx86AssemblerTests methodsFor:'tests-FPU'!
+
+testFXCH
+
+    self 
+        assert: [ :a|
+        a fxch "the same as: asm fxch: asm ST1" ]
+        bytes: #[	2r11011001 2r11001001 ]
+    
+!
+
+testFXCHST1
+
+    self 
+        assert: [ :a| a fxch: asm ST1 ]
+        bytes: #[	2r11011001 2r11001001 ]
+    
+! !
+
+!AJx86AssemblerTests methodsFor:'tests-data'!
+
+setUpDataBytes
+    ^ self setUpDataBytesAlign: 1
+!
+
+setUpDataBytesAlign: alignToBytes
+
+    asm nop.
+    asm align: alignToBytes.
+    ^ asm db: 16r12.
+!
+
+testDataBytes
+    
+    |data|
+    data := self setUpDataBytes.
+    
+    self assert: asm bytes equals: #[144   16r12].
+!
+
+testDataBytesAlignDouble
+    
+    |data|
+    data := self setUpDataBytesAlign: 4.
+    
+    self assert: asm bytes equals: #[144   0 0 0 16r12].
+!
+
+testDataBytesAlignQuad
+    
+    |data|
+    data := self setUpDataBytesAlign: 8. 
+    self assert: asm bytes equals: #[144   0 0 0   0 0 0 0   16r12].
+!
+
+testDataBytesAlignWord
+    
+    |data|
+    data := self setUpDataBytesAlign: 2.
+    
+    self assert: asm bytes equals: #[144   0 16r12].
+!
+
+testDataDouble
+    
+    | data|
+    
+    asm nop.
+    data := asm dd: #[16r78 16r56 16r34 16r12].
+    
+    self assert: asm bytes equals: #[144   16r78 16r56 16r34 16r12].
+!
+
+testDataWord
+    
+    | data|
+    asm nop.
+    data := asm dw: #[16r34 16r12].
+    
+    self assert: asm bytes equals: #[144   16r34 16r12].
+    
+    
+! !
+
+!AJx86AssemblerTests methodsFor:'utility'!
+
+asmShould: aBlock raise: anError
+
+    self should: [self bytes: aBlock] raise: anError.
+!
+
+assert: aBlock bytes: aByteArray
+
+    self assert: (self bytes: aBlock) equals: aByteArray .
+!
+
+bytes: aBlock
+    asm := self newAssembler.
+    aBlock value: asm.
+    ^ asm bytes
+!
+
+newAssembler 
+    ^ AJx86Assembler new
+        noStackFrame;
+        yourself
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx86GPRegister.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,150 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJRegister subclass:#AJx86GPRegister
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:'AJx86Registers'
+	category:'AsmJit-x86-Operands'
+!
+
+AJx86GPRegister comment:'A general purpose x86 & x64 registers'
+!
+
+!AJx86GPRegister methodsFor:'accessing'!
+
+descriptionOn: s
+    s nextPutAll: 'A '; print: self size * 8; nextPutAll: 'bit general purpose register'.
+!
+
+registerName 
+    ^ name asString.
+!
+
+stackSize
+    ^ self size
+! !
+
+!AJx86GPRegister methodsFor:'converting'!
+
+as16
+    ^ self isHighByte
+        ifTrue: [ self asLowByte as16 ]
+        ifFalse: [ 
+            AJx86Registers
+                generalPurposeWithIndex: self index
+                size: 2
+                requiresRex: self index > 7
+                prohibitsRex: false ]
+!
+
+as32
+    ^ self isHighByte
+        ifTrue: [ self asLowByte as32 ]
+        ifFalse: [ 
+            AJx86Registers
+                generalPurposeWithIndex: self index
+                size: 4
+                requiresRex: self index > 7
+                prohibitsRex: false ]
+!
+
+as64
+    ^ self isHighByte
+        ifTrue: [ self asLowByte as64 ]
+        ifFalse: [ 
+            AJx86Registers
+                generalPurposeWithIndex: self index
+                size: 8
+                requiresRex: self index > 7
+                prohibitsRex: false ]
+!
+
+as8
+    "8-bit low-byte registers require REX if they have a high index (>7), or if they are one of BPL, SIL, DIL, SPL (indices 4-7).
+    The only way to get AH, BH, CH, or DH out of this method is to send it to one of those registers."
+
+    ^ self is8
+        ifTrue: [ self ]
+        ifFalse: [ 
+            AJx86Registers
+                generalPurposeWithIndex: self index
+                size: 1
+                requiresRex: self index > 3
+                prohibitsRex: false ]
+!
+
+asHighByte
+    self isHighByte
+        ifTrue: [ ^ self ].
+    self isLowByte
+        ifFalse: [ Error signal: 'Can only convert AH, BH, CH, or DH to high byte' ].
+    ^ AJx86Registers
+        generalPurposeWithIndex: self index + 2r100
+        size: 1
+        requiresRex: false
+        prohibitsRex: true
+!
+
+asLowByte
+    self isLowByte
+        ifTrue: [ ^ self ].
+    self isHighByte
+        ifFalse: [ Error signal: 'Can only convert high byte 8bit register to low byte' ].
+    ^ AJx86Registers
+        generalPurposeWithIndex: self index - 2r100
+        size: 1
+        requiresRex: false
+        prohibitsRex: false
+!
+
+ptr
+
+    "turn receiver into a memory operand with receiver as base"
+    
+    ^ AJMem new base: self
+! !
+
+!AJx86GPRegister methodsFor:'emitting'!
+
+emitModRM: emitter code: rCode immSize: immSize
+
+    "Receiver is register, hence mod = 3 
+    immSize is ignored"
+
+    ^ emitter emitMod: 3 reg: rCode rm: self code
+! !
+
+!AJx86GPRegister methodsFor:'printing'!
+
+printAsMemBaseOn: aStream
+
+    aStream nextPutAll: self registerName 
+!
+
+printOn: aStream
+    
+    aStream nextPutAll: self registerName 
+! !
+
+!AJx86GPRegister methodsFor:'testing'!
+
+isGeneralPurpose
+    ^ true
+!
+
+isHighByte
+    "return true for 8bit high-byte registers (AH - DH)"
+
+    ^ self prohibitsRex
+!
+
+isLowByte
+    "return true for 8bit low-byte register (AL - DL)"
+
+    "Note that this does *not* answer true for all byte registers -- send #is8 for that."
+
+    ^ self code <= 3
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx86Instruction.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,332 @@
+"{ Encoding: utf8 }"
+
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJInstruction subclass:#AJx86Instruction
+	instanceVariableNames:'description'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-x86-Instructions'
+!
+
+AJx86Instruction comment:''
+!
+
+!AJx86Instruction methodsFor:'accessing'!
+
+description
+    ^ description
+!
+
+description: anInstructionDescription
+    description := anInstructionDescription
+!
+
+instructionDesciptions
+    ^ AJx86InstructionDescription instructions
+! !
+
+!AJx86Instruction methodsFor:'code generation'!
+
+emitByte: byte
+
+    self assert: byte isByte.
+    machineCode nextPut: byte 
+!
+
+emitCode: asm
+    "do not generate machine code if it is already there"
+    machineCode ifNotNil: [ ^ self ].
+    
+    "make sure all operands are converted"
+    operands ifNotNil: [ operands := operands collect: #asAJOperand ].
+    
+    machineCode := WriteStream on: (ByteArray new: 16).		
+    description emitUsing: self operands: operands.
+
+    machineCode := machineCode contents.
+!
+
+emitDWord: dword
+
+ 	"Emit dword (4 bytes) in little-endian order (since our target it x86 anyways)"
+	
+	self 
+		emitByte: (dword bitAnd: 255);
+		emitByte: (dword>>8 bitAnd: 255);
+		
+		emitByte: (dword>>16 bitAnd: 255);
+		emitByte: (dword>>24 bitAnd: 255)
+		
+!
+
+emitImmediate: imm size: size
+
+    ^ imm emitUsing: self size: size
+!
+
+emitMod: mod reg: reg rm: rm
+    "Emit MODR/M byte.
+    mmrrrxxx
+    
+    mm = mod
+    rrr = REG (r8/r16/r32/mm/xmm
+    xxx = r/m
+    "
+    
+    ^ self emitByte: (mod & 3) << 3 + (reg & 7) << 3 + (rm & 7)
+    
+!
+
+emitOpCode: opCode
+    | byte |
+    "instruction prefix"
+    (byte := (opCode bitAnd: 16rFF000000)) = 0 ifFalse: [
+        self emitByte: byte >> 24 ].
+    (byte := (opCode bitAnd: 16r00FF0000)) = 0 ifFalse: [
+        self emitByte: byte >> 16 ].
+    (byte := (opCode bitAnd: 16r0000FF00)) = 0 ifFalse: [
+        self emitByte: byte >> 8 ].
+    self emitByte: (opCode bitAnd: 16rFF).
+    
+!
+
+emitQWord: dword
+
+ 	"Emit a qword (8 bytes) in little-endian order (since our target it x86 anyways)"
+	
+	self 
+		emitByte: (dword bitAnd: 255);
+		emitByte: (dword>>8 bitAnd: 255);
+		
+		emitByte: (dword>>16 bitAnd: 255);
+		emitByte: (dword>>24 bitAnd: 255);
+		
+		emitByte: (dword>>32 bitAnd: 255);
+		emitByte: (dword>>40 bitAnd: 255);
+		
+		emitByte: (dword>>48 bitAnd: 255);
+		emitByte: (dword>>56 bitAnd: 255)
+		
+!
+
+emitRexForInteger: anInt op2: op2
+    
+    self emitRexPrefixW: op2 is64 R: false X: false  B:  op2 isUpperBank.
+!
+
+emitRexForOp1: op1 op2: op2
+    "op1 is the general-purpose register argument (or a register number).
+    op2 is the reg/mem argument.
+    
+    In 64-bit mode, the instruction's default operation size is 32 bits. 
+    Use of the REX.W prefix promotes operation to 64 bits. 
+    Use of the REX.R prefix permits access to additional registers (R8-R15) for the op1 (reg) register. 
+    Use of the REX.B prefix permits access to additional registers (R8-R15) for the op2 (r/m) register, or the base register of op2 if register indirect. 
+    Use of the REX.X prefix permits access to additional registers (R8-R15) for the index register of op2, if indexed.
+    See the summary chart at the beginning of this section for encoding data and limits."
+
+    | requires64Bit |
+    "no-op in 32 bit mode"
+    self is32BitMode
+        ifTrue: [ ^ self ].
+    op1 isInteger
+        ifTrue: [ ^ self emitRexForInteger: op1 op2: op2 ].
+    requires64Bit := op1 is64 or: [ op2 isReg and: [ op2 is64 ] ].
+    self
+        emitRexPrefixW: requires64Bit
+        R: op1 isUpperBank
+        X: op2 hasUpperBankIndex
+        B: op2 isUpperBank
+!
+
+emitRexForSingleOperand: op
+    "In 64-bit mode, the instruction’s default operation size is 32 bits. 
+    Use of the REX.W prefix promotes operation to 64 bits. 
+    Use of the REX.B prefix permits access to additional registers (R8-R15). 
+    See the summary chart at the beginning of this section for encoding data and limits."
+     
+    self emitRexPrefixW: op is64 R: false X: false B: op isUpperBank .
+!
+
+emitRexPrefixW: w R: r X: x B: b
+    "
+    field  bit   def
+    -      7-4   2r0100 REX prefix identifier
+    W      3     0 = Operand size determined by CS.D
+                 1 = 64 Bit Operand Size
+    R      2     Extension of the ModR/M reg field
+    X      1     Extension of the SIB index field
+    B      0     Extension of the ModR/M r/m field. SIB base field, or Opcode reg field
+    "
+
+    self requiresRex
+        ifTrue: [ 
+            self is32BitMode
+                ifTrue: [ self error: 'Attempt to use a 64-bit-specific instruction or operand in 32-bit mode' ]
+                ifFalse: [ self emitByte: 2r0100 << 4 | (w asBit << 3) | (r asBit << 2) | (x asBit << 1) | b asBit ] ]
+!
+
+emitRexR: w opReg: opReg regCode: regCode
+    "no-op in 32 bit mode"
+    
+!
+
+emitRexRM: opRequires64Bit regCode: regCode rm: rm
+    
+    self emitRexPrefixW: opRequires64Bit R: (regCode > 7) X: false B: rm isUpperBank
+    
+!
+
+emitScale: shift index: indexCode base: baseCode
+    self emitByte: ((shift << 3) + (indexCode bitAnd: 7) << 3) + (baseCode bitAnd: 7)
+!
+
+emitSegmentPrefix: aMem
+
+    (aMem isMem and: [ aMem hasSegmentPrefix ]) ifTrue: [
+        self emitByte: aMem segmentPrefixCode.
+    ]
+!
+
+emitX86Inl: opCode reg: reg
+    "Emit instruction where register is inlined to opcode."
+
+    ^ self emitX86Inl: opCode reg: reg withRex: true
+!
+
+emitX86Inl: opCode reg: reg withRex: useREX
+    "Emit instruction where register is inlined to opcode."
+
+    | byte |
+    "16 bit prefix"
+    reg size == 2 
+        ifTrue: [ self emitByte: 16r66 ].
+    
+    "instruction prefix"
+    (byte := (opCode bitAnd: 16rFF000000)) = 0 ifFalse: [
+        self emitByte: byte >> 24 ].
+    
+    useREX ifTrue: [ self emitRexForSingleOperand: reg ].
+    
+    (byte := (opCode bitAnd: 16r00FF0000)) = 0 ifFalse: [
+        self emitByte: byte >> 16 ].
+
+    (byte := (opCode bitAnd: 16r0000FF00)) = 0 ifFalse: [
+        self emitByte: byte >> 8 ].
+
+    self emitByte: (opCode bitAnd: 16rFF) + (reg code bitAnd: 7).
+!
+
+emitX86RM: opCode size: aSize regOrCode: regOrCode rm: regOrMem 
+"Emit instruction with reg/memory operand."
+    
+    ^ self emitX86RM: opCode size: aSize regOrCode: regOrCode rm: regOrMem immSize: 0
+!
+
+emitX86RM: opCode size: aSize regOrCode: regOrCode rm: regOrMem immSize: immSize
+    "Emit instruction with reg/memory operand."
+    
+    | byte code |
+    code := regOrCode isInteger ifTrue: [ regOrCode ] ifFalse: [ regOrCode code ].
+
+    "16 bit prefix"
+    aSize == 2 ifTrue: [ self emitByte: 16r66 ].
+    
+    "segment prefix"
+    self emitSegmentPrefix: regOrMem.
+    "instruction prefix"
+    (byte := (opCode bitAnd: 16rFF000000)) = 0 ifFalse: [
+        self emitByte: byte >> 24 ].
+    
+    self emitRexForOp1: regOrCode op2: regOrMem.
+    
+    (byte := (opCode bitAnd: 16r00FF0000)) = 0 ifFalse: [
+        self emitByte: byte >> 16 ].
+
+    (byte := (opCode bitAnd: 16r0000FF00)) = 0 ifFalse: [
+        self emitByte: byte >> 8 ].
+
+    self emitByte: (opCode bitAnd: 16rFF).
+
+    "ModR/M"
+    ^ regOrMem emitModRM: self code: code immSize: immSize
+!
+
+setLabelPosition: label
+    "set label position for immediate operand(s), if any"
+    label position: self position + machineCode size.  
+! !
+
+!AJx86Instruction methodsFor:'code generation - prefixes'!
+
+emitOperandSizeOverridePrefix: anOperand
+    "If creating 64bit code, this must be called last of the prefix-generators, as the 64-bit prefixes are required to precede the opcode"
+
+    "Switch to 16-bit operand mode for the next opcode if necessary"
+    anOperand is16 ifTrue: [ self emitByte: 16r66].
+    self emitRexRM: anOperand is64 regCode: 0 rm: anOperand
+    
+    
+! !
+
+!AJx86Instruction methodsFor:'consistency'!
+
+checkOperandsForConflict
+    "Signal an error if the given operands cannot be used together. Must be sent after operands are set."
+
+    | prohibited required |
+    required := self requiresRex.
+    prohibited := false.
+    operands
+        do: [ :op | 
+            (op isInteger not and: [ op prohibitsRex ])
+                ifTrue: [ prohibited := true ] ].
+    prohibited & required
+        ifTrue: [ self error: 'Mix of operands that require and prohibit a REX prefix' ]
+! !
+
+!AJx86Instruction methodsFor:'emitting code'!
+
+emitWord: aWord 
+
+    "little-endian"
+    
+    self 
+        emitByte: (aWord bitAnd: 255);
+        emitByte: ((aWord >> 8) bitAnd: 255)
+    
+! !
+
+!AJx86Instruction methodsFor:'testing'!
+
+is32BitMode
+
+    ^ true
+!
+
+is64BitMode
+    ^ false
+!
+
+isGPNRegister: reg
+
+    "answer true if given register is native general purpose register,
+    matching the target native size i.e. 32 bits for x86 or 64 bits for x64"
+    ^ reg isGeneralPurpose and: [ reg size = 4 ]
+!
+
+requiresRex
+    ^false
+! !
+
+!AJx86Instruction methodsFor:'visitor'!
+
+accept: anObject
+    "generic instruction"
+    ^ anObject visitInstruction: self
+    
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx86InstructionDescription.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,1628 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#AJx86InstructionDescription
+	instanceVariableNames:'name group comment description o1Flags o2Flags opCodeR opCode1
+		opCode2 groupEmitSelector'
+	classVariableNames:''
+	poolDictionaries:'AJConstants AJx86Registers'
+	category:'AsmJit-x86-Instructions'
+!
+
+AJx86InstructionDescription class instanceVariableNames:'instructions reference'
+
+"
+ No other class instance variables are inherited by this class.
+"
+!
+
+AJx86InstructionDescription comment:''
+!
+
+!AJx86InstructionDescription class methodsFor:'initialization'!
+
+at: instructionName
+    
+    ^ instructions 
+        at: instructionName 
+!
+
+initInstructions
+    " self initInstructions "
+    | data |
+
+    instructions := IdentityDictionary new.
+
+    data := OrderedCollection new.
+    data addAll: self instructionData;
+        addAll: self instructionsCDQ;
+        addAll: self instructionsOther.
+    
+    data do: [:dt | 
+        instructions at: dt first put: (self fromArray: dt) ].
+    
+    ^ instructions
+!
+
+initialize
+
+    self initInstructions.
+!
+
+instructionData
+^ #(
+(#adc #alu 0 0 "R" 2 "C1" 16r00000010 "C2" 16r00000080 )
+(#add #alu 0 0 "R" 0 0 "C2" 16r00000080 )
+(#addpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F58 0 )
+(#addps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F58 0 )
+(#addsd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F58 0 )
+(#addss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F58 0 )
+(#addsubpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000FD0 0 )
+(#addsubps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000FD0 0 )
+(#amdprefetch #mem "op1" 2r1000000 0 "R" 0 "C1" 16r00000F0D 0 )
+(#amdprefetchw #mem "op1" 2r1000000 0 "R" 1 "C1" 16r00000F0D 0 )
+(#and #alu 0 0 "R" 4 "C1" 16r00000020 "C2" 16r00000080 )
+(#andnpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F55 0 )
+(#andnps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F55 0 )
+(#andpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F54 0 )
+(#andps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F54 0 )
+(#blendpd #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A0D 0 )
+(#blendps #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A0C 0 )
+(#blendvpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3815 0 )
+(#blendvps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3814 0 )
+(#bsf #rrm 0 0 "R" 0 "C1" 16r00000FBC 0 )
+(#bsr #rrm 0 0 "R" 0 "C1" 16r00000FBD 0 )
+(#bswap #bswap 0 0 "R" 0 0 0 )
+(#bt #bt "op1" 2r1001110 "op2" 2r10001110 "R" 4 "C1" 16r00000FA3 "C2" 16r00000FBA )
+(#btc #bt "op1" 2r1001110 "op2" 2r10001110 "R" 7 "C1" 16r00000FBB "C2" 16r00000FBA )
+(#btr #bt "op1" 2r1001110 "op2" 2r10001110 "R" 6 "C1" 16r00000FB3 "C2" 16r00000FBA )
+(#bts #bt "op1" 2r1001110 "op2" 2r10001110 "R" 5 "C1" 16r00000FAB "C2" 16r00000FBA )
+(#call #call 0 0 "R" 0 0 0 )
+(#clc #emit 0 0 "R" 0 "C1" 16r000000F8 0 )
+(#cld #emit 0 0 "R" 0 "C1" 16r000000FC 0 )
+(#clflush #mem "op1" 2r1000000 0 "R" 7 "C1" 16r00000FAE 0 )
+(#cmc #emit 0 0 "R" 0 "C1" 16r000000F5 0 )
+(#cmova #rrm 0 0 "R" 0 "C1" 16r00000F47 0 )
+(#cmovae #rrm 0 0 "R" 0 "C1" 16r00000F43 0 )
+(#cmovb #rrm 0 0 "R" 0 "C1" 16r00000F42 0 )
+(#cmovbe #rrm 0 0 "R" 0 "C1" 16r00000F46 0 )
+(#cmovc #rrm 0 0 "R" 0 "C1" 16r00000F42 0 )
+(#cmove #rrm 0 0 "R" 0 "C1" 16r00000F44 0 )
+(#cmovg #rrm 0 0 "R" 0 "C1" 16r00000F4F 0 )
+(#cmovge #rrm 0 0 "R" 0 "C1" 16r00000F4D 0 )
+(#cmovl #rrm 0 0 "R" 0 "C1" 16r00000F4C 0 )
+(#cmovle #rrm 0 0 "R" 0 "C1" 16r00000F4E 0 )
+(#cmovna #rrm 0 0 "R" 0 "C1" 16r00000F46 0 )
+(#cmovnae #rrm 0 0 "R" 0 "C1" 16r00000F42 0 )
+(#cmovnb #rrm 0 0 "R" 0 "C1" 16r00000F43 0 )
+(#cmovnbe #rrm 0 0 "R" 0 "C1" 16r00000F47 0 )
+(#cmovnc #rrm 0 0 "R" 0 "C1" 16r00000F43 0 )
+(#cmovne #rrm 0 0 "R" 0 "C1" 16r00000F45 0 )
+(#cmovng #rrm 0 0 "R" 0 "C1" 16r00000F4E 0 )
+(#cmovnge #rrm 0 0 "R" 0 "C1" 16r00000F4C 0 )
+(#cmovnl #rrm 0 0 "R" 0 "C1" 16r00000F4D 0 )
+(#cmovnle #rrm 0 0 "R" 0 "C1" 16r00000F4F 0 )
+(#cmovno #rrm 0 0 "R" 0 "C1" 16r00000F41 0 )
+(#cmovnp #rrm 0 0 "R" 0 "C1" 16r00000F4B 0 )
+(#cmovns #rrm 0 0 "R" 0 "C1" 16r00000F49 0 )
+(#cmovnz #rrm 0 0 "R" 0 "C1" 16r00000F45 0 )
+(#cmovo #rrm 0 0 "R" 0 "C1" 16r00000F40 0 )
+(#cmovp #rrm 0 0 "R" 0 "C1" 16r00000F4A 0 )
+(#cmovpe #rrm 0 0 "R" 0 "C1" 16r00000F4A 0 )
+(#cmovpo #rrm 0 0 "R" 0 "C1" 16r00000F4B 0 )
+(#cmovs #rrm 0 0 "R" 0 "C1" 16r00000F48 0 )
+(#cmovz #rrm 0 0 "R" 0 "C1" 16r00000F44 0 )
+(#cmp #alu 0 0 "R" 7 "C1" 16r00000038 "C2" 16r00000080 )
+(#cmppd #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000FC2 0 )
+(#cmpps #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000FC2 0 )
+(#cmpsd #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000FC2 0 )
+(#cmpss #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000FC2 0 )
+(#cmpxchg #rmr 0 0 "R" 0 "C1" 16r00000FB0 0 )
+(#cmpxchg16b #mem "op1" 2r1000000 0 "R" 1 "C1" 16r00000FC7 "C2" 16r00000001 )
+(#cmpxchg8b #mem "op1" 2r1000000 0 "R" 1 "C1" 16r00000FC7 0 )
+(#comisd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F2F 0 )
+(#comiss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F2F 0 )
+(#cpuid #emit 0 0 "R" 0 "C1" 16r00000FA2 0 )
+(#crc32 #crc32 0 0 "R" 0 "C1" 16rF20F38F0 0 )
+(#cvtdq2pd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000FE6 0 )
+(#cvtdq2ps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F5B 0 )
+(#cvtpd2dq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000FE6 0 )
+(#cvtpd2pi #mmurmi "op1" 2r10000 "op2" 2r1100000 "R" 0 "C1" 16r66000F2D 0 )
+(#cvtpd2ps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F5A 0 )
+(#cvtpi2pd #mmurmi "op1" 2r100000 "op2" 2r1010000 "R" 0 "C1" 16r66000F2A 0 )
+(#cvtpi2ps #mmurmi "op1" 2r100000 "op2" 2r1010000 "R" 0 "C1" 16r00000F2A 0 )
+(#cvtps2dq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F5B 0 )
+(#cvtps2pd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F5A 0 )
+(#cvtps2pi #mmurmi "op1" 2r10000 "op2" 2r1100000 "R" 0 "C1" 16r00000F2D 0 )
+(#cvtsd2si #mmurmi "op1" 2r1100 "op2" 2r1100000 "R" 0 "C1" 16rF2000F2D 0 )
+(#cvtsd2ss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F5A 0 )
+(#cvtsi2sd #mmurmi "op1" 2r100000 "op2" 2r1001100 "R" 0 "C1" 16rF2000F2A 0 )
+(#cvtsi2ss #mmurmi "op1" 2r100000 "op2" 2r1001100 "R" 0 "C1" 16rF3000F2A 0 )
+(#cvtss2sd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F5A 0 )
+(#cvtss2si #mmurmi "op1" 2r1100 "op2" 2r1100000 "R" 0 "C1" 16rF3000F2D 0 )
+(#cvttpd2dq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000FE6 0 )
+(#cvttpd2pi #mmurmi "op1" 2r10000 "op2" 2r1100000 "R" 0 "C1" 16r66000F2C 0 )
+(#cvttps2dq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F5B 0 )
+(#cvttps2pi #mmurmi "op1" 2r10000 "op2" 2r1100000 "R" 0 "C1" 16r00000F2C 0 )
+(#cvttsd2si #mmurmi "op1" 2r1100 "op2" 2r1100000 "R" 0 "C1" 16rF2000F2C 0 )
+(#cvttss2si #mmurmi "op1" 2r1100 "op2" 2r1100000 "R" 0 "C1" 16rF3000F2C 0 )
+(#daa #emit #x86 0 "R" 0 "C1" 16r00000027 0 )
+(#das #emit #x86 0 "R" 0 "C1" 16r0000002F 0 )
+(#dec #incdec 0 0 "R" 1 "C1" 16r00000048 "C2" 16r000000FE )
+(#div #rm 0 0 "R" 6 "C1" 16r000000F6 0 )
+(#divpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F5E 0 )
+(#divps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F5E 0 )
+(#divsd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F5E 0 )
+(#divss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F5E 0 )
+(#dppd #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A41 0 )
+(#dpps #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A40 0 )
+(#emms #emit 0 0 "R" 0 "C1" 16r00000F77 0 )
+(#enter #enter 0 0 "R" 0 "C1" 16r000000C8 0 )
+(#extractps #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A17 0 )
+(#f2xm1 #emit 0 0 "R" 0 "C1" 16r0000D9F0 0 )
+(#fabs #emit 0 0 "R" 0 "C1" 16r0000D9E1 0 )
+(#fadd #x87fpu 0 0 "R" 0 "C1" 16rD8DCC0C0 0 )
+(#faddp #x87sti 0 0 "R" 0 "C1" 16r0000DEC0 0 )
+(#fbld #mem "op1" 2r1000000 0 "R" 4 "C1" 16r000000DF 0 )
+(#fbstp #mem "op1" 2r1000000 0 "R" 6 "C1" 16r000000DF 0 )
+(#fchs #emit 0 0 "R" 0 "C1" 16r0000D9E0 0 )
+(#fclex #emit 0 0 "R" 0 "C1" 16r9B00DBE2 0 )
+(#fcmovb #x87sti 0 0 "R" 0 "C1" 16r0000DAC0 0 )
+(#fcmovbe #x87sti 0 0 "R" 0 "C1" 16r0000DAD0 0 )
+(#fcmove #x87sti 0 0 "R" 0 "C1" 16r0000DAC8 0 )
+(#fcmovnb #x87sti 0 0 "R" 0 "C1" 16r0000DBC0 0 )
+(#fcmovnbe #x87sti 0 0 "R" 0 "C1" 16r0000DBD0 0 )
+(#fcmovne #x87sti 0 0 "R" 0 "C1" 16r0000DBC8 0 )
+(#fcmovnu #x87sti 0 0 "R" 0 "C1" 16r0000DBD8 0 )
+(#fcmovu #x87sti 0 0 "R" 0 "C1" 16r0000DAD8 0 )
+(#fcom #x87fpu 0 0 "R" 2 "C1" 16rD8DCD0D0 0 )
+(#fcomi #x87sti 0 0 "R" 0 "C1" 16r0000DBF0 0 )
+(#fcomip #x87sti 0 0 "R" 0 "C1" 16r0000DFF0 0 )
+(#fcomp #x87fpu 0 0 "R" 3 "C1" 16rD8DCD8D8 0 )
+(#fcompp #emit 0 0 "R" 0 "C1" 16r0000DED9 0 )
+(#fcos #emit 0 0 "R" 0 "C1" 16r0000D9FF 0 )
+(#fdecstp #emit 0 0 "R" 0 "C1" 16r0000D9F6 0 )
+(#fdiv #x87fpu 0 0 "R" 6 "C1" 16rD8DCF0F8 0 )
+(#fdivp #x87sti 0 0 "R" 0 "C1" 16r0000DEF8 0 )
+(#fdivr #x87fpu 0 0 "R" 7 "C1" 16rD8DCF8F0 0 )
+(#fdivrp #x87sti 0 0 "R" 0 "C1" 16r0000DEF0 0 )
+(#ffree #x87sti 0 0 "R" 0 "C1" 16r0000DDC0 0 )
+(#fiadd #x87mem "op1" 2r110 0 "R" 0 "C1" 16rDEDA0000 0 )
+(#ficom #x87mem "op1" 2r110 0 "R" 2 "C1" 16rDEDA0000 0 )
+(#ficomp #x87mem "op1" 2r110 0 "R" 3 "C1" 16rDEDA0000 0 )
+(#fidiv #x87mem "op1" 2r110 0 "R" 6 "C1" 16rDEDA0000 0 )
+(#fidivr #x87mem "op1" 2r110 0 "R" 7 "C1" 16rDEDA0000 0 )
+(#fild #x87mem "op1" 2r1110 0 "R" 0 "C1" 16rDFDBDF05 0 )
+(#fimul #x87mem "op1" 2r110 0 "R" 1 "C1" 16rDEDA0000 0 )
+(#fincstp #emit 0 0 "R" 0 "C1" 16r0000D9F7 0 )
+(#finit #emit 0 0 "R" 0 "C1" 16r9B00DBE3 0 )
+(#fist #x87mem "op1" 2r110 0 "R" 2 "C1" 16rDFDB0000 0 )
+(#fistp #x87mem "op1" 2r1110 0 "R" 3 "C1" 16rDFDBDF07 0 )
+(#fisttp #x87mem "op1" 2r1110 0 "R" 1 "C1" 16rDFDBDD01 0 )
+(#fisub #x87mem "op1" 2r110 0 "R" 4 "C1" 16rDEDA0000 0 )
+(#fisubr #x87mem "op1" 2r110 0 "R" 5 "C1" 16rDEDA0000 0 )
+(#fld #x87memSti "op1" 2r11100 0 "R" 0 "C1" 16r00D9DD00 "C2" 16rD9C0DB05 )
+(#fld1 #emit 0 0 "R" 0 "C1" 16r0000D9E8 0 )
+(#fldcw #mem "op1" 2r1000000 0 "R" 5 "C1" 16r000000D9 0 )
+(#fldenv #mem "op1" 2r1000000 0 "R" 4 "C1" 16r000000D9 0 )
+(#fldl2e #emit 0 0 "R" 0 "C1" 16r0000D9EA 0 )
+(#fldl2t #emit 0 0 "R" 0 "C1" 16r0000D9E9 0 )
+(#fldlg2 #emit 0 0 "R" 0 "C1" 16r0000D9EC 0 )
+(#fldln2 #emit 0 0 "R" 0 "C1" 16r0000D9ED 0 )
+(#fldpi #emit 0 0 "R" 0 "C1" 16r0000D9EB 0 )
+(#fldz #emit 0 0 "R" 0 "C1" 16r0000D9EE 0 )
+(#fmul #x87fpu 0 0 "R" 1 "C1" 16rD8DCC8C8 0 )
+(#fmulp #x87sti 0 0 "R" 0 "C1" 16r0000DEC8 0 )
+(#fnclex #emit 0 0 "R" 0 "C1" 16r0000DBE2 0 )
+(#fninit #emit 0 0 "R" 0 "C1" 16r0000DBE3 0 )
+(#fnop #emit 0 0 "R" 0 "C1" 16r0000D9D0 0 )
+(#fnsave #mem "op1" 2r1000000 0 "R" 6 "C1" 16r000000DD 0 )
+(#fnstcw #mem "op1" 2r1000000 0 "R" 7 "C1" 16r000000D9 0 )
+(#fnstenv #mem "op1" 2r1000000 0 "R" 6 "C1" 16r000000D9 0 )
+(#fnstsw #x87fstsw "op1" 2r1000000 0 "R" 7 "C1" 16r000000DD "C2" 16r0000DFE0 )
+(#fpatan #emit 0 0 "R" 0 "C1" 16r0000D9F3 0 )
+(#fprem #emit 0 0 "R" 0 "C1" 16r0000D9F8 0 )
+(#fprem1 #emit 0 0 "R" 0 "C1" 16r0000D9F5 0 )
+(#fptan #emit 0 0 "R" 0 "C1" 16r0000D9F2 0 )
+(#frndint #emit 0 0 "R" 0 "C1" 16r0000D9FC 0 )
+(#frstor #mem "op1" 2r1000000 0 "R" 4 "C1" 16r000000DD 0 )
+(#fsave #mem "op1" 2r1000000 0 "R" 6 "C1" 16r9B0000DD 0 )
+(#fscale #emit 0 0 "R" 0 "C1" 16r0000D9FD 0 )
+(#fsin #emit 0 0 "R" 0 "C1" 16r0000D9FE 0 )
+(#fsincos #emit 0 0 "R" 0 "C1" 16r0000D9FB 0 )
+(#fsqrt #emit 0 0 "R" 0 "C1" 16r0000D9FA 0 )
+(#fst #x87memSti "op1" 2r1100 0 "R" 2 "C1" 16r00D9DD02 "C2" 16rDDD00000 )
+(#fstcw #mem "op1" 2r1000000 0 "R" 7 "C1" 16r9B0000D9 0 )
+(#fstenv #mem "op1" 2r1000000 0 "R" 6 "C1" 16r9B0000D9 0 )
+(#fstp #x87memSti "op1" 2r11100 0 "R" 3 "C1" 16r00D9DD03 "C2" 16rDDD8DB07 )
+(#fstsw #x87fstsw "op1" 2r1000000 0 "R" 7 "C1" 16r9B0000DD "C2" 16r9B00DFE0 )
+(#fsub #x87fpu 0 0 "R" 4 "C1" 16rD8DCE0E8 0 )
+(#fsubp #x87sti 0 0 "R" 0 "C1" 16r0000DEE8 0 )
+(#fsubr #x87fpu 0 0 "R" 5 "C1" 16rD8DCE8E0 0 )
+(#fsubrp #x87sti 0 0 "R" 0 "C1" 16r0000DEE0 0 )
+(#ftst #emit 0 0 "R" 0 "C1" 16r0000D9E4 0 )
+(#fucom #x87sti 0 0 "R" 0 "C1" 16r0000DDE0 0 )
+(#fucomi #x87sti 0 0 "R" 0 "C1" 16r0000DBE8 0 )
+(#fucomip #x87sti 0 0 "R" 0 "C1" 16r0000DFE8 0 )
+(#fucomp #x87sti 0 0 "R" 0 "C1" 16r0000DDE8 0 )
+(#fucompp #emit 0 0 "R" 0 "C1" 16r0000DAE9 0 )
+(#fwait #emit 0 0 "R" 0 "C1" 16r0000009B 0 )
+(#fxam #emit 0 0 "R" 0 "C1" 16r0000D9E5 0 )
+(#fxch #x87sti 0 0 "R" 0 "C1" 16r0000D9C8 0 )
+(#fxrstor #mem 0 0 "R" 1 "C1" 16r00000FAE 0 )
+(#fxsave #mem 0 0 "R" 0 "C1" 16r00000FAE 0 )
+(#fxtract #emit 0 0 "R" 0 "C1" 16r0000D9F4 0 )
+(#fyl2x #emit 0 0 "R" 0 "C1" 16r0000D9F1 0 )
+(#fyl2xp1 #emit 0 0 "R" 0 "C1" 16r0000D9F9 0 )
+(#haddpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F7C 0 )
+(#haddps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F7C 0 )
+(#hsubpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F7D 0 )
+(#hsubps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F7D 0 )
+(#idiv #rm 0 0 "R" 7 "C1" 16r000000F6 0 )
+(#imul #imul 0 0 "R" 0 0 0 )
+(#inc #incdec 0 0 "R" 0 "C1" 16r00000040 "C2" 16r000000FE )
+(#int3 #emit 0 0 "R" 0 "C1" 16r000000CC 0 )
+(#ja #cjmp 0 0 "R" 0 "C1" 16r00000007 0 )
+(#jae #cjmp 0 0 "R" 0 "C1" 16r00000003 0 )
+(#jb #cjmp 0 0 "R" 0 "C1" 16r00000002 0 )
+(#jbe #cjmp 0 0 "R" 0 "C1" 16r00000006 0 )
+(#jc #cjmp 0 0 "R" 0 "C1" 16r00000002 0 )
+(#je #cjmp 0 0 "R" 0 "C1" 16r00000004 0 )
+(#jg #cjmp 0 0 "R" 0 "C1" 16r0000000F 0 )
+(#jge #cjmp 0 0 "R" 0 "C1" 16r0000000D 0 )
+(#jl #cjmp 0 0 "R" 0 "C1" 16r0000000C 0 )
+(#jle #cjmp 0 0 "R" 0 "C1" 16r0000000E 0 )
+(#jmp #jmp 0 0 "R" 0 0 0 )
+(#jna #cjmp 0 0 "R" 0 "C1" 16r00000006 0 )
+(#jnae #cjmp 0 0 "R" 0 "C1" 16r00000002 0 )
+(#jnb #cjmp 0 0 "R" 0 "C1" 16r00000003 0 )
+(#jnbe #cjmp 0 0 "R" 0 "C1" 16r00000007 0 )
+(#jnc #cjmp 0 0 "R" 0 "C1" 16r00000003 0 )
+(#jne #cjmp 0 0 "R" 0 "C1" 16r00000005 0 )
+(#jng #cjmp 0 0 "R" 0 "C1" 16r0000000E 0 )
+(#jnge #cjmp 0 0 "R" 0 "C1" 16r0000000C 0 )
+(#jnl #cjmp 0 0 "R" 0 "C1" 16r0000000D 0 )
+(#jnle #cjmp 0 0 "R" 0 "C1" 16r0000000F 0 )
+(#jno #cjmp 0 0 "R" 0 "C1" 16r00000001 0 )
+(#jnp #cjmp 0 0 "R" 0 "C1" 16r0000000B 0 )
+(#jns #cjmp 0 0 "R" 0 "C1" 16r00000009 0 )
+(#jnz #cjmp 0 0 "R" 0 "C1" 16r00000005 0 )
+(#jo #cjmp 0 0 "R" 0 0 0 )
+(#jp #cjmp 0 0 "R" 0 "C1" 16r0000000A 0 )
+(#jpe #cjmp 0 0 "R" 0 "C1" 16r0000000A 0 )
+(#jpo #cjmp 0 0 "R" 0 "C1" 16r0000000B 0 )
+(#js #cjmp 0 0 "R" 0 "C1" 16r00000008 0 )
+(#jz #cjmp 0 0 "R" 0 "C1" 16r00000004 0 )
+(#lddqu #mmurmi "op1" 2r100000 "op2" 2r1000000 "R" 0 "C1" 16rF2000FF0 0 )
+(#ldmxcsr #mem "op1" 2r1000000 0 "R" 2 "C1" 16r00000FAE 0 )
+(#lea #lea 0 0 "R" 0 0 0 )
+(#leave #emit 0 0 "R" 0 "C1" 16r000000C9 0 )
+(#lfence #emit 0 0 "R" 0 "C1" 16r000FAEE8 0 )
+(#lock #emit 0 0 "R" 0 "C1" 16r000000F0 0 )
+(#maskmovdqu #mmurmi "op1" 2r100000 "op2" 2r100000 "R" 0 "C1" 16r66000F57 0 )
+(#maskmovq #mmurmi "op1" 2r10000 "op2" 2r10000 "R" 0 "C1" 16r00000FF7 0 )
+(#maxpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F5F 0 )
+(#maxps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F5F 0 )
+(#maxsd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F5F 0 )
+(#maxss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F5F 0 )
+(#mfence #emit 0 0 "R" 0 "C1" 16r000FAEF0 0 )
+(#minpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F5D 0 )
+(#minps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F5D 0 )
+(#minsd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F5D 0 )
+(#minss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F5D 0 )
+(#monitor #emit 0 0 "R" 0 "C1" 16r000F01C8 0 )
+(#mov #mov 0 0 "R" 0 0 0 )
+(#movPtr #movPtr 0 0 "R" 0 0 0 )
+(#movapd #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F28 "C2" 16r66000F29 )
+(#movaps #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F28 "C2" 16r00000F29 )
+(#movbe #movbe "op1" 2r1001110 "op2" 2r1001110 "R" 0 "C1" 16r000F38F0 "C2" 16r000F38F1 )
+(#movd #mmuMovD 0 0 "R" 0 0 0 )
+(#movddup #mmuMov "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F12 0 )
+(#movdq2q #mmuMov "op1" 2r10000 "op2" 2r100000 "R" 0 "C1" 16rF2000FD6 0 )
+(#movdqa #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F6F "C2" 16r66000F7F )
+(#movdqu #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F6F "C2" 16rF3000F7F )
+(#movhlps #mmuMov "op1" 2r100000 "op2" 2r100000 "R" 0 "C1" 16r00000F12 0 )
+(#movhpd #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F16 "C2" 16r66000F17 )
+(#movhps #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F16 "C2" 16r00000F17 )
+(#movlhps #mmuMov "op1" 2r100000 "op2" 2r100000 "R" 0 "C1" 16r00000F16 0 )
+(#movlpd #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F12 "C2" 16r66000F13 )
+(#movlps #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F12 "C2" 16r00000F13 )
+(#movmskpd #mmuMov "op1" 2r1101 "op2" 2r100000 "R" 0 "C1" 16r66000F50 0 )
+(#movmskps #mmuMov "op1" 2r1101 "op2" 2r100000 "R" 0 "C1" 16r00000F50 0 )
+(#movntdq #mmuMov "op1" 2r1000000 "op2" 2r100000 "R" 0 0 "C2" 16r66000FE7 )
+(#movntdqa #mmuMov "op1" 2r100000 "op2" 2r1000000 "R" 0 "C1" 16r660F382A 0 )
+(#movnti #mmuMov "op1" 2r1000000 "op2" 2r1100 "R" 0 0 "C2" 16r00000FC3 )
+(#movntpd #mmuMov "op1" 2r1000000 "op2" 2r100000 "R" 0 0 "C2" 16r66000F2B )
+(#movntps #mmuMov "op1" 2r1000000 "op2" 2r100000 "R" 0 0 "C2" 16r00000F2B )
+(#movntq #mmuMov "op1" 2r1000000 "op2" 2r10000 "R" 0 0 "C2" 16r00000FE7 )
+(#movq #mmuMovQ 0 0 "R" 0 0 0 )
+(#movq2dq #mmurmi "op1" 2r100000 "op2" 2r10000 "R" 0 "C1" 16rF3000FD6 0 )
+(#movsd #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F10 "C2" 16rF2000F11 )
+(#movshdup #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F16 0 )
+(#movsldup #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F12 0 )
+(#movss #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F10 "C2" 16rF3000F11 )
+(#movsx #movSxZx 0 0 "R" 0 "C1" 16r00000FBE 0 )
+(#movsxd #movsxd 0 0 "R" 0 0 0 )
+(#movupd #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F10 "C2" 16r66000F11 )
+(#movups #mmuMov "op1" 2r1100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F10 "C2" 16r00000F11 )
+(#movzx #movSxZx 0 0 "R" 0 "C1" 16r00000FB6 0 )
+(#mpsadbw #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A42 0 )
+(#mul #rm 0 0 "R" 4 "C1" 16r000000F6 0 )
+(#mulpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F59 0 )
+(#mulps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F59 0 )
+(#mulsd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F59 0 )
+(#mulss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F59 0 )
+(#mwait #emit 0 0 "R" 0 "C1" 16r000F01C9 0 )
+(#neg #rm 0 0 "R" 3 "C1" 16r000000F6 0 )
+(#nop #emit 0 0 "R" 0 "C1" 16r00000090 0 )
+(#not #rm 0 0 "R" 2 "C1" 16r000000F6 0 )
+(#or #alu 0 0 "R" 1 "C1" 16r00000008 "C2" 16r00000080 )
+(#orpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F56 0 )
+(#orps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F56 0 )
+(#pabsb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F381C 0 )
+(#pabsd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F381E 0 )
+(#pabsw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F381D 0 )
+(#packssdw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F6B 0 )
+(#packsswb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F63 0 )
+(#packusdw #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F382B 0 )
+(#packuswb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F67 0 )
+(#paddb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FFC 0 )
+(#paddd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FFE 0 )
+(#paddq #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FD4 0 )
+(#paddsb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FEC 0 )
+(#paddsw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FED 0 )
+(#paddusb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FDC 0 )
+(#paddusw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FDD 0 )
+(#paddw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FFD 0 )
+(#palignr #mmuRmImm8 "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3A0F 0 )
+(#pand #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FDB 0 )
+(#pandn #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FDF 0 )
+(#pause #emit 0 0 "R" 0 "C1" 16rF3000090 0 )
+(#pavgb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FE0 0 )
+(#pavgw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FE3 0 )
+(#pblendvb #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3810 0 )
+(#pblendw #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A0E 0 )
+(#pcmpeqb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F74 0 )
+(#pcmpeqd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F76 0 )
+(#pcmpeqq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3829 0 )
+(#pcmpeqw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F75 0 )
+(#pcmpestri #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A61 0 )
+(#pcmpestrm #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A60 0 )
+(#pcmpgtb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F64 0 )
+(#pcmpgtd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F66 0 )
+(#pcmpgtq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3837 0 )
+(#pcmpgtw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F65 0 )
+(#pcmpistri #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A63 0 )
+(#pcmpistrm #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A62 0 )
+(#pextrb #mmuPextr "op1" 2r1000101 "op2" 2r100000 "R" 0 "C1" 16r000F3A14 0 )
+(#pextrd #mmuPextr "op1" 2r1000100 "op2" 2r100000 "R" 0 "C1" 16r000F3A16 0 )
+(#pextrq #mmuPextr "op1" 2r1001100 "op2" 2r100000 "R" 1 "C1" 16r000F3A16 0 )
+(#pextrw #mmuPextr "op1" 2r1000100 "op2" 2r110000 "R" 0 "C1" 16r000F3A16 0 )
+(#pf2id #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r0000001D )
+(#pf2iw #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r0000001C )
+(#pfacc #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000AE )
+(#pfadd #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r0000009E )
+(#pfcmpeq #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000B0 )
+(#pfcmpge #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r00000090 )
+(#pfcmpgt #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000A0 )
+(#pfmax #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000A4 )
+(#pfmin #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r00000094 )
+(#pfmul #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000B4 )
+(#pfnacc #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r0000008A )
+(#pfpnacc #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r0000008E )
+(#pfrcp #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r00000096 )
+(#pfrcpit1 #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000A6 )
+(#pfrcpit2 #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000B6 )
+(#pfrsqit1 #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000A7 )
+(#pfrsqrt #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r00000097 )
+(#pfsub #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r0000009A )
+(#pfsubr #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000AA )
+(#phaddd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3802 0 )
+(#phaddsw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3803 0 )
+(#phaddw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3801 0 )
+(#phminposuw #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3841 0 )
+(#phsubd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3806 0 )
+(#phsubsw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3807 0 )
+(#phsubw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3805 0 )
+(#pi2fd #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r0000000D )
+(#pi2fw #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r0000000C )
+(#pinsrb #mmuRmImm8 "op1" 2r100000 "op2" 2r1000100 "R" 0 "C1" 16r660F3A20 0 )
+(#pinsrd #mmuRmImm8 "op1" 2r100000 "op2" 2r1000100 "R" 0 "C1" 16r660F3A22 0 )
+(#pinsrq #mmuRmImm8 "op1" 2r100000 "op2" 2r1001000 "R" 0 "C1" 16r660F3A22 0 )
+(#pinsrw #mmuRmImm8 "op1" 2r110000 "op2" 2r1000100 "R" 0 "C1" 16r00000FC4 0 )
+(#pmaddubsw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3804 0 )
+(#pmaddwd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FF5 0 )
+(#pmaxsb #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F383C 0 )
+(#pmaxsd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F383D 0 )
+(#pmaxsw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FEE 0 )
+(#pmaxub #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FDE 0 )
+(#pmaxud #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F383F 0 )
+(#pmaxuw #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F383E 0 )
+(#pminsb #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3838 0 )
+(#pminsd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3839 0 )
+(#pminsw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FEA 0 )
+(#pminub #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FDA 0 )
+(#pminud #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F383B 0 )
+(#pminuw #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F383A 0 )
+(#pmovmskb #mmurmi "op1" 2r1100 "op2" 2r110000 "R" 0 "C1" 16r00000FD7 0 )
+(#pmovsxbd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3821 0 )
+(#pmovsxbq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3822 0 )
+(#pmovsxbw #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3820 0 )
+(#pmovsxdq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3825 0 )
+(#pmovsxwd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3823 0 )
+(#pmovsxwq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3824 0 )
+(#pmovzxbd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3831 0 )
+(#pmovzxbq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3832 0 )
+(#pmovzxbw #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3830 0 )
+(#pmovzxdq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3835 0 )
+(#pmovzxwd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3833 0 )
+(#pmovzxwq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3834 0 )
+(#pmuldq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3828 0 )
+(#pmulhrsw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F380B 0 )
+(#pmulhuw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FE4 0 )
+(#pmulhw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FE5 0 )
+(#pmulld #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3840 0 )
+(#pmullw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FD5 0 )
+(#pmuludq #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FF4 0 )
+(#pop #pop 0 0 "R" 0 "C1" 16r00000058 "C2" 16r0000008F )
+(#popad #emit #x86 0 "R" 0 "C1" 16r00000061 0 )
+(#popcnt #rrm 0 0 "R" 0 "C1" 16rF3000FB8 0 )
+(#popfd #emit 0 0 "R" 0 "C1" 16r0000009D 0 )
+(#popfq #emit 0 0 "R" 0 "C1" 16r4800009D 0 )
+(#por #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FEB 0 )
+(#prefetch #mmuPrefetch "op1" 2r1000000 "op2" 2r10000000 "R" 0 0 0 )
+(#psadbw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FF6 0 )
+(#pshufb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3800 0 )
+(#pshufd #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F70 0 )
+(#pshufhw #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F70 0 )
+(#pshuflw #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F70 0 )
+(#pshufw #mmuRmImm8 "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F70 0 )
+(#psignb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3808 0 )
+(#psignd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F380A 0 )
+(#psignw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r000F3809 0 )
+(#pslld #mmurmi "op1" 2r110000 "op2" 2r11110000 "R" 6 "C1" 16r00000FF2 "C2" 16r00000F72 )
+(#pslldq #mmurmi "op1" 2r100000 "op2" 2r10000000 "R" 7 0 "C2" 16r66000F73 )
+(#psllq #mmurmi "op1" 2r110000 "op2" 2r11110000 "R" 6 "C1" 16r00000FF3 "C2" 16r00000F73 )
+(#psllw #mmurmi "op1" 2r110000 "op2" 2r11110000 "R" 6 "C1" 16r00000FF1 "C2" 16r00000F71 )
+(#psrad #mmurmi "op1" 2r110000 "op2" 2r11110000 "R" 4 "C1" 16r00000FE2 "C2" 16r00000F72 )
+(#psraw #mmurmi "op1" 2r110000 "op2" 2r11110000 "R" 4 "C1" 16r00000FE1 "C2" 16r00000F71 )
+(#psrld #mmurmi "op1" 2r110000 "op2" 2r11110000 "R" 2 "C1" 16r00000FD2 "C2" 16r00000F72 )
+(#psrldq #mmurmi "op1" 2r100000 "op2" 2r10000000 "R" 3 0 "C2" 16r66000F73 )
+(#psrlq #mmurmi "op1" 2r110000 "op2" 2r11110000 "R" 2 "C1" 16r00000FD3 "C2" 16r00000F73 )
+(#psrlw #mmurmi "op1" 2r110000 "op2" 2r11110000 "R" 2 "C1" 16r00000FD1 "C2" 16r00000F71 )
+(#psubb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FF8 0 )
+(#psubd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FFA 0 )
+(#psubq #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FFB 0 )
+(#psubsb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FE8 0 )
+(#psubsw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FE9 0 )
+(#psubusb #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FD8 0 )
+(#psubusw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FD9 0 )
+(#psubw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FF9 0 )
+(#pswapd #mmuRm3DNow "op1" 2r10000 "op2" 2r1010000 "R" 0 "C1" 16r00000F0F "C2" 16r000000BB )
+(#ptest #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3817 0 )
+(#punpckhbw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F68 0 )
+(#punpckhdq #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F6A 0 )
+(#punpckhqdq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F6D 0 )
+(#punpckhwd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F69 0 )
+(#punpcklbw #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F60 0 )
+(#punpckldq #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F62 0 )
+(#punpcklqdq #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F6C 0 )
+(#punpcklwd #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000F61 0 )
+(#push #push 0 0 "R" 6 "C1" 16r00000050 "C2" 16r000000FF )
+(#pushad #emit #x86 0 "R" 0 "C1" 16r00000060 0 )
+(#pushf #emit 0 0 "R" 0 "C1" 16r6600009C 0 )
+(#pushfd #emit #x86 0 "R" 0 "C1" 16r0000009C 0 )
+(#pushfq #emit #x64 0 "R" 0 "C1" 16r0000009C 0 )
+(#pxor #mmurmi "op1" 2r110000 "op2" 2r1110000 "R" 0 "C1" 16r00000FEF 0 )
+(#rcl #rot 0 0 "R" 2 0 0 )
+(#rcpps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F53 0 )
+(#rcpss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F53 0 )
+(#rcr #rot 0 0 "R" 3 0 0 )
+(#rdtsc #emit 0 0 "R" 0 "C1" 16r00000F31 0 )
+(#rdtscp #emit 0 0 "R" 0 "C1" 16r000F01F9 0 )
+(#ret #ret 0 0 "R" 0 0 0 )
+(#rol #rot 0 0 "R" 0 0 0 )
+(#ror #rot 0 0 "R" 1 0 0 )
+(#roundpd #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A09 0 )
+(#roundps #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A08 0 )
+(#roundsd #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A0B 0 )
+(#roundss #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r660F3A0A 0 )
+(#rsqrtps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F52 0 )
+(#rsqrtss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F52 0 )
+(#sahf #emit 0 0 "R" 0 "C1" 16r0000009E 0 )
+(#sal #rot 0 0 "R" 4 0 0 )
+(#sar #rot 0 0 "R" 7 0 0 )
+(#sbb #alu 0 0 "R" 3 "C1" 16r00000018 "C2" 16r00000080 )
+(#sfence #emit 0 0 "R" 0 "C1" 16r000FAEF8 0 )
+(#shl #rot 0 0 "R" 4 0 0 )
+(#shld #shldShrd 0 0 "R" 0 "C1" 16r00000FA4 0 )
+(#shr #rot 0 0 "R" 5 0 0 )
+(#shrd #shldShrd 0 0 "R" 0 "C1" 16r00000FAC 0 )
+(#shufps #mmuRmImm8 "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000FC6 0 )
+(#sqrtpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F51 0 )
+(#sqrtps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F51 0 )
+(#sqrtsd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F51 0 )
+(#sqrtss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F51 0 )
+(#stc #emit 0 0 "R" 0 "C1" 16r000000F9 0 )
+(#std #emit 0 0 "R" 0 "C1" 16r000000FD 0 )
+(#stmxcsr #mem "op1" 2r1000000 0 "R" 3 "C1" 16r00000FAE 0 )
+(#sub #alu 0 0 "R" 5 "C1" 16r00000028 "C2" 16r00000080 )
+(#subpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F5C 0 )
+(#subps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F5C 0 )
+(#subsd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF2000F5C 0 )
+(#subss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16rF3000F5C 0 )
+(#syscall #emit "op1" 2r100000000 0 "R" 0 "C1" 16r00000F05 0 )
+(#test #test 0 0 "R" 0 0 0 )
+(#ucomisd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F2E 0 )
+(#ucomiss #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F2E 0 )
+(#ud2 #emit 0 0 "R" 0 "C1" 16r00000F0B 0 )
+(#unpckhpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F15 0 )
+(#unpckhps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F15 0 )
+(#unpcklpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F14 0 )
+(#unpcklps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F14 0 )
+(#xadd #rmr 0 0 "R" 0 "C1" 16r00000FC0 0 )
+(#xchg #xchg 0 0 "R" 0 0 0 )
+(#xor #alu 0 0 "R" 6 "C1" 16r00000030 "C2" 16r00000080 )
+(#xorpd #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r66000F57 0 )
+(#xorps #mmurmi "op1" 2r100000 "op2" 2r1100000 "R" 0 "C1" 16r00000F57 0 )
+
+)
+!
+
+instructionsCDQ
+
+"CBW/CWDE/CDQE Convert Byte to Word/Convert Word to
+Doubleword/Convert Doubleword to Quadword"
+^#(
+
+(#cbw #emit 0 0 "R" 0 "C1" 16r66000098 0 )
+(#cwde #emit 0 0 "R" 0 "C1" 16r00000098 0 )
+(#cdqe #emit #x64 0 "R" 0 "C1" 16r48000098 0 )
+
+"CWD/CDQ/CQO Convert Word to Doubleword/Convert Doubleword to
+Quadword"
+
+(#cwd #emit 0 0 "R" 0 "C1" 16r66000099 0 )
+(#cdq #emit 0 0 "R" 0 "C1" 16r00000099 0 )
+(#cqo #emit #x64 0 "R" 0 "C1" 16r48000099 0 )
+
+)
+!
+
+instructionsOther
+
+^ #(
+
+(#femms #emit 0 0 "R" 0 "C1" 16r00000F0E 0 )  " looks like invalid one "
+
+(#movsb #emit 0 0 "R" 0 "C1" 16r000000A4 0 )  
+(#movsd #emit 0 0 "R" 0 "C1" 16r000000A5 0 )   "in 64bit mode - moves 64bits"
+(#rep #emit 0 0 "R" 0 "C1" 16r000000F3 0 )   "repeat prefix"
+(#repe #emit 0 0 "R" 0 "C1" 16r000000F3 0 )   "repeat prefix"
+(#repz #emit 0 0 "R" 0 "C1" 16r000000F3 0 )   "repeat prefix"
+(#repne #emit 0 0 "R" 0 "C1" 16r000000F2 0 )   "repeat prefix"
+(#repnz #emit 0 0 "R" 0 "C1" 16r000000F2 0 )   "repeat prefix"
+
+
+(#cmpsb #emit 0 0 "R" 0 "C1" 16r000000A6 0 )  
+"(#cmpsw #emit 0 0 0  16r000000A7 0 )  "
+(#cmpsd #emit 0 0 "R" 0 "C1" 16r000000A7 0 )  
+
+)
+! !
+
+!AJx86InstructionDescription class methodsFor:'instance creation'!
+
+fromArray: aSpecArray
+    ^ self basicNew
+        fromArray: aSpecArray
+! !
+
+!AJx86InstructionDescription class methodsFor:'accessing'!
+
+instructions
+    ^ instructions ifNil: [ self initInstructions ]
+! !
+
+!AJx86InstructionDescription class methodsFor:'printing'!
+
+printInstructions
+    " AJInstructionDescription printInstructions.
+    
+    AJInstructionDescription printInstructions openInWorkspaceWithTitle: 'x86 instructions'
+     "
+    ^ String streamContents: [:str | self printInstructionsOn: str ]
+!
+
+printInstructionsOn: aStream
+    " AJInstructionDescription printInstructionsOn: (FileStream newFileNamed: 'asm.st'). "
+    
+    aStream nextPutAll: '#(' ; cr.
+    
+    self instructions keys asSortedCollection do: [:aname | 
+        | instr |
+        
+        instr := instructions at: aname.
+        
+        instr printOn: aStream.
+        aStream cr.
+    ].
+    aStream cr;
+        nextPut: $); cr
+! !
+
+!AJx86InstructionDescription class methodsFor:'testing'!
+
+checkInstructionsIntegrity
+
+    " self checkInstructionsIntegrity"
+    | data |
+    
+    data := self instructionData.
+    
+    data do: [:dt | | instr |
+        
+        instr := instructions at: dt first.
+
+        self assert: [
+            (instr name = (dt at: 1)) &
+            (instr group = (dt at: 2)) &
+            (instr o1Flags = (dt at:3)) &
+            (instr o2Flags = (dt at:4)) &
+            (instr opCodeR = (dt at:5)) &
+            (instr opCode1 = (dt at:6)) &
+            (instr opCode2 = (dt at:7)) 
+        ].
+    ].
+! !
+
+!AJx86InstructionDescription methodsFor:'accessing'!
+
+comment
+    ^ comment
+!
+
+comment: aString
+    comment := aString
+!
+
+description
+    ^ description
+!
+
+description: aString
+    description := aString
+!
+
+group
+    ^ group
+!
+
+group: anObject
+    "Set the value of group"
+
+    group := anObject
+!
+
+name
+    ^ name
+!
+
+name: anObject
+    "Set the value of name"
+
+    name := anObject
+!
+
+o1Flags
+    "Answer the value of o1Flags"
+
+    ^ o1Flags
+!
+
+o1Flags: anObject
+    "Set the value of o1Flags"
+
+    o1Flags := anObject
+!
+
+o2Flags
+    "Answer the value of o2Flags"
+
+    ^ o2Flags
+!
+
+o2Flags: anObject
+    "Set the value of o2Flags"
+
+    o2Flags := anObject
+!
+
+opCode1
+    "Answer the value of opCode1"
+
+    ^ opCode1
+!
+
+opCode1: anObject
+    "Set the value of opCode1"
+
+    opCode1 := anObject
+!
+
+opCode2
+    "Answer the value of opCode2"
+
+    ^ opCode2
+!
+
+opCode2: anObject
+    "Set the value of opCode2"
+
+    opCode2 := anObject
+!
+
+opCodeR
+    "Answer the value of opCodeR"
+
+    ^ opCodeR
+!
+
+opCodeR: anObject
+    "Set the value of opCodeR"
+
+    opCodeR := anObject
+! !
+
+!AJx86InstructionDescription methodsFor:'code emitting'!
+
+emittest: emitter operand1: op1 operand2: op2 operand3: op3
+    | immSize |
+    op1 isRegMem & op2 isReg
+        ifTrue: [ 
+            op1 size notNil & (op1 size ~= op2 size)
+                ifTrue: [ 
+                    self
+                        error:
+                            'Operands ' , op1 asString , ' and ' , op2 asString , ' don''t match in size: ' , op1 size asString , ' !!= '
+                                , op2 size asString ].
+            ^ emitter
+                emitX86RM: 16r84 + op2 isRegTypeGPB not asBit
+                size: op2 size
+                regOrCode: op2
+                rm: op1 ].
+    (op1 isReg and: [ op1 index = 0 and: [ op2 isImm ] ])
+        ifTrue: [ 
+            immSize := op1 size min: 4.
+            op1 is16
+                ifTrue: [ emitter emitByte: 16r66	"16bit" ].
+            emitter emitRexRM: op1 is64 regCode: 0 rm: op1.
+            emitter emitByte: 16rA8 + (op1 size ~= 1) asBit.
+            ^ emitter emitImmediate: op2 size: immSize ].
+    (op1 isRegMem and: [ op2 isImm ])
+        ifFalse: [ self invalidInstruction ].
+    immSize := op1 size min: 4.
+    (op2 fitsInSize: immSize)
+        ifFalse: [ self invalidInstruction ].
+    emitter emitSegmentPrefix: op1.
+    emitter emitOperandSizeOverridePrefix: op1.
+    emitter emitByte: 16rF6 + (op1 size ~= 1) asBit.
+    op1 emitModRM: emitter code: 0 immSize: immSize.
+    emitter emitImmediate: op2 size: immSize
+! !
+
+!AJx86InstructionDescription methodsFor:'emitting'!
+
+emitalu: emitter operand1: op1 operand2: op2 operand3: op3
+    | opCode opReg |
+    opCode := opCode1.
+    opReg := opCodeR.
+    
+    " Mem <- Reg "
+    (op1 isMem and: [ op2 isReg ]) ifTrue: [
+        ^ emitter emitX86RM: opCode + op2 isRegTypeGPB not asBit
+            size: op2 size
+            regOrCode: op2
+            rm: op1
+    ].
+
+    "Reg <- Reg|Mem"
+    (op1 isReg and: [op2 isRegMem]) ifTrue: [
+        ^ emitter emitX86RM: opCode + 2 + op1 isRegTypeGPB not asBit
+            size: op1 size
+            regOrCode: op1
+            rm: op2
+    ].
+
+    op2 isImm ifFalse: [	self invalidInstruction ].
+
+    "short constant"
+    op2 isInt8 ifTrue: [
+ 		| szBits |
+        szBits := op1 size = 1 ifTrue: [ 0 ] ifFalse: [ 3 ].
+        emitter emitX86RM: opCode2 + szBits
+            size: op1 size
+            regOrCode: opReg
+            rm: op1
+            immSize: 1.
+        ^ emitter emitImmediate: op2 size: 1.
+    ].
+    
+      " AL, AX, EAX, RAX register shortcuts"
+    (op1 isRegIndex: 0) ifTrue: [
+        
+        op1 isRegTypeGPW ifTrue: [ emitter emitByte: 16r66 " 16 bit " ].
+        op1 isRegTypeGPQ ifTrue: [ emitter emitByte: 16r48 " REX.W" ].
+
+        emitter emitByte: (opReg << 3 bitOr: (16r04 + op1 isRegTypeGPB not asBit)).
+        ^ emitter emitImmediate: op2 size: (op1 size min: 4)
+    ].
+
+    (op1 isRegMem) ifTrue: [ | immSize szBits |
+        immSize := op2 isInt8 ifTrue: [1] ifFalse: [ op1 size min: 4].
+        szBits := op1 size ~= 1 ifTrue: [ immSize ~= 1 ifTrue: [1] ifFalse: [3]] ifFalse: [ 0].
+        emitter emitX86RM: opCode2 + szBits
+            size: op1 size
+            regOrCode: opReg
+            rm: op1
+            immSize: immSize.
+        ^ emitter emitImmediate: op2 size: immSize.
+    ].
+
+    self invalidInstruction.
+    
+!
+
+emitbswap: emitter operand1: op1 operand2: op2 operand3: op3
+
+    op1 isReg ifTrue: [
+
+        emitter emitRexR: op1 isRegTypeGPQ opReg: 1 regCode: op1 code.
+        emitter emitByte: 16r0F.
+        ^ emitter emitModR: 1 r: op1 code
+    ].
+    self invalidInstruction.
+!
+
+emitbt: emitter operand1: dst operand2: src operand3: op3
+
+    dst isRegMem
+        ifFalse: [ self error: 'Expected register or memory but got ', dst asString ].
+    
+    (dst isReg and: [ dst is8 ])
+        ifTrue: [ self error: '8 bit register ', dst asString, ' not supported for bit test operations'].
+    
+ 	src isReg ifTrue: [
+        ^ emitter emitX86RM: opCode1
+            size: src size
+            regOrCode: src
+            rm: dst
+    ].
+
+    src isImm ifTrue: [
+        src isInt8 
+            ifFalse: [ self error: 'Expected imm8 but got ', src size asString, ' immediate.' ].
+        emitter emitX86RM: opCode2
+            size: dst size
+            regOrCode: opCodeR
+            rm: dst
+            immSize: 1.
+        ^ emitter emitImmediate: src size: 1
+    ].
+
+    self invalidInstruction
+    
+!
+
+emitcall: emitter operand1: op1 operand2: op2 operand3: op3
+
+    (op1 isMem or: [ op1 isReg and: [ op1 index = 0 "EAX" ] ]) ifTrue: [
+        ^ emitter emitX86RM:  16rFF
+            size: 4
+            regOrCode: 2  
+            rm: op1  
+    ].
+
+    op1 isImm ifTrue: [ "call by relative offset, you should be really sure what you're' doing"
+        emitter emitByte: 16rE8. 
+        op1 emitUsing: emitter size: 4.
+        ^ self.
+        ].
+    
+    op1 isLabel ifTrue: [
+        emitter emitByte: 16rE8. 
+        emitter emitDisplacement: op1 inlinedDisp: -4.
+        ^ self
+    ].
+    self invalidInstruction.
+!
+
+emitcjmp: emitter operand1: target operand2: hint operand3: op3
+    "Conditional jump.
+    Use only symbols as labels"
+
+    
+    target isString ifTrue: [
+        "jump on label"
+        ^ emitter addJump: target condition: opCode1 hint: hint
+    ].
+    
+    "we could check if label is bound , and emit short jump, 
+    instead of 32-bit relative jump address"
+    self invalidInstruction.
+    emitter emitByte: 16r0F;
+        emitByte: (16r80 bitOr: opCode1);
+        emitDisplacement: target inlinedDisp: -4
+!
+
+emitcrc32: emitter operand1: dst operand2: src operand3: op3
+
+    (dst isReg and: [ src isRegMem ]) ifTrue: [
+        self assert: (dst isRegTypeGPD | dst isRegTypeGPQ).
+
+        ^ emitter emitX86RM: opCode1 + (src size ~= 1) asBit
+            size: src size
+            regOrCode: dst
+            rm: src
+        ].
+    
+    self invalidInstruction.
+!
+
+emitemit: emitter operand1: op1 operand2: op2 operand3: op3
+
+    ^ emitter emitOpCode: opCode1
+!
+
+emitenter: emitter operand1: op1 operand2: op2 operand3: op3
+
+    (op1 isImm and: [ op2 isImm ]) ifFalse: [ self invalidInstruction ].
+    
+    emitter emitByte: 16rC8.
+    emitter emitImmediate: op1 size: 2.
+    emitter emitImmediate: op2 size: 1.
+!
+
+emitimul: emitter operand1: op1 operand2: op2 operand3: op3
+    | immSize |
+    
+    op1 isRegMem ifFalse: [  ^ self invalidInstruction ].
+    
+    " 1 operand "
+    (op2 isNil and: [ op3 isNil ]) ifTrue: [
+        ^ emitter emitX86RM:  16rF6 + (op1 size ~= 1) asBit
+            size: op1 size
+            regOrCode:  5
+            rm:  op1
+        ].
+    op1 isReg ifFalse: [  ^ self invalidInstruction ].
+    
+    "2 operands"
+    op3 isNil ifTrue: [
+"		self assert: op1 isRegTypeGPW."
+
+        op2 isRegMem ifTrue: [
+            ^ emitter emitX86RM: 16r0FAF
+                size: op1 size
+                regOrCode: op1 code
+                rm:  op2
+            ].
+        op2 isImm ifFalse: [ ^ self invalidInstruction ].
+
+        (op2 isInt8 and: [ op2 relocMode == #RelocNone ]) ifTrue: [
+            emitter emitX86RM: 16r6B
+                size: op1 size
+                regOrCode:  op1 code
+                rm:  op1
+                immSize: 1.
+            ^ emitter emitImmediate: op2 size: 1.
+            ].
+
+        immSize := op1 isRegTypeGPW ifTrue: [ 2 ] ifFalse: [ 4 ].
+        emitter emitX86RM: 16r69
+            size: op1 size
+            regOrCode:  op1 code
+            rm:  op1
+            immSize: immSize.
+        ^ emitter emitImmediate: op2 size: immSize.
+    ].
+
+    " 3 operands "
+    (op2 isRegMem and: [op3 isImm ]) ifFalse: [ ^ self invalidInstruction ].
+    
+    (op3 isInt8 and: [ op3 relocMode == #RelocNone ]) ifTrue: [
+        emitter emitX86RM: 16r6B
+            size: op1 size
+            regOrCode:  op1
+            rm: op2 immSize: 1.
+        ^ emitter emitImmediate: op3 size: 1.
+        ].
+
+    	immSize := op1 isRegTypeGPW ifTrue: [2] ifFalse: [4].
+    emitter emitX86RM: 16r69
+        size: op1 size
+        regOrCode:  op1
+        rm:  op2 immSize: immSize.
+    emitter emitImmediate: op3 size: immSize.
+!
+
+emitincdec: emitter operand1: dst operand2: op2 operand3: op3
+
+    dst isRegMem ifFalse: [ ^ self invalidInstruction ].
+
+    "INC [r16|r32] in 64 bit mode is not encodable."
+    emitter is32BitMode ifTrue: [
+        (dst isReg & dst isRegTypeGPW & dst isRegTypeGPD) ifTrue: [ 
+        ^ emitter emitX86Inl: opCode1	reg: dst
+    ]].
+
+    emitter emitX86RM:  opCode2 + (dst size ~= 1) asBit
+        size: dst size
+        regOrCode:  opCodeR
+        rm:  dst
+!
+
+emitjmp: emitter operand1: target operand2: op2 operand3: op3
+    
+    target isString ifTrue: [
+        "jump on label"
+        ^ emitter addJump: target condition: nil hint: nil
+    ].
+
+    target isRegMem ifTrue: [
+        ^ emitter emitX86RM: 16rFF
+            size: 0 
+            regOrCode:  4
+            rm:  target
+    ].
+
+    emitter emitByte: 16rE9.
+    emitter emitDisplacement: target inlinedDisp: -4
+!
+
+emitlea: emitter operand1: op1 operand2: op2 operand3: op3
+
+    (op1 isReg and: [ op2 isMem ]) 
+        ifFalse: [ self error: 'LEA: Expected Reg and Mem but got ', op1 asString, ' and ', op2 asString ].
+    
+    emitter emitX86RM: 16r8D
+        size: op1 size
+        regOrCode: op1
+        rm: op2
+!
+
+emitmem: emitter operand1: op1 operand2: op2 operand3: op3
+
+    op1 isMem ifFalse: [ self invalidInstruction ].
+
+    self assert: (opCode2 = 0 or: [ opCode2 = 1 ]).
+    emitter emitX86RM: opCode1
+        size: opCode2 << 3
+        regOrCode: opCodeR 
+        rm: op1
+!
+
+emitmmuMov: emitter operand1: op1 operand2: op2 operand3: op3
+    
+    self shouldBeImplemented.
+    
+    self assert: o1Flags ~= 0.
+    self assert: o2Flags ~= 0.
+    
+      "Check parameters (X)MM|GP32_64 <- (X)MM|GP32_64|Mem|Imm"
+    (op1 isMem & ((o1Flags bitAnd: OMEM) = 0)) |
+    (op1 isRegTypeMM & ((o1Flags bitAnd: OMM) = 0)) |
+    (op1 isRegTypeXMM & ((o1Flags bitAnd: OXMM) = 0)) |
+    (op1 isRegTypeGPD & ((o1Flags bitAnd: OG32) = 0)) |
+    (op1 isRegTypeGPQ & ((o1Flags bitAnd: OG64) = 0)) |
+    (op2 isRegTypeMM & ((o2Flags bitAnd: OMM) = 0)) |
+    (op2 isRegTypeXMM & ((o2Flags bitAnd: OXMM) = 0)) |
+    (op2 isRegTypeGPD & ((o2Flags bitAnd: OG32) = 0)) |
+    (op2 isRegTypeGPQ & ((o2Flags bitAnd: OG64) = 0)) |
+    (op2 isMem & ((o2Flags bitAnd: OMEM) = 0)) |
+    (op1 isMem & op2 isMem)
+        ifTrue: [ self invalidInstruction ].
+    
+        
+!
+
+emitmmuMovD: emitter operand1: op1 operand2: op2 operand3: op3
+    self shouldBeImplemented
+!
+
+emitmmuMovQ: emitter operand1: op1 operand2: op2 operand3: op3
+    self shouldBeImplemented
+!
+
+emitmmuPextr: emitter operand1: op1 operand2: op2 operand3: op3
+    self shouldBeImplemented
+!
+
+emitmmuPrefetch: emitter operand1: op1 operand2: op2 operand3: op3
+    self shouldBeImplemented
+!
+
+emitmmuRm3DNow: emitter operand1: op1 operand2: op2 operand3: op3
+    self shouldBeImplemented
+!
+
+emitmmuRmImm8: emitter operand1: op1 operand2: op2 operand3: op3
+    self shouldBeImplemented
+!
+
+emitmmurmi: emitter operand1: op1 operand2: op2 operand3: op3
+    self shouldBeImplemented
+!
+
+emitmov: emitter operand1: dst operand2: src operand3: op3
+
+    src isReg & dst isReg ifTrue: [
+        self assert: (src isRegTypeGPB | src isRegTypeGPW | src isRegTypeGPD | src isRegTypeGPQ ).
+        ]. 
+    
+    " reg <- mem "
+    dst isReg & src isRegMem ifTrue: [
+        self assert: (dst isRegTypeGPB | dst isRegTypeGPW | dst isRegTypeGPD | dst isRegTypeGPQ ).
+    "	(src size = dst size) ifFalse: [ self invalidInstruction ]. "
+        ^ emitter emitX86RM: 16r0000008A + dst isRegTypeGPB not asBit 
+            size:  dst size 
+            regOrCode:  dst 
+            rm: src
+        ].
+
+    " reg <- imm "
+    
+    dst isReg & src isImm ifTrue: [
+        | immSize |
+        immSize := dst size.
+        emitter is64BitMode & immSize = 8 & src isInt32 & (src relocMode == #RelocNone) ifTrue: [
+            "Optimize instruction size by using 32 bit immediate if value can fit to it"
+             emitter emitX86RM: 16rC7
+                size: dst size
+                regOrCode: 0 rm: dst.
+                immSize := 4
+        ] ifFalse: [
+            emitter emitX86Inl: (immSize=1 ifTrue: [16rB0] ifFalse: [16rB8]) reg: dst
+        ].
+        ^ emitter emitImmediate: src size: immSize
+    ].
+
+    "mem <- reg"
+    dst isMem & src isReg ifTrue: [
+        self assert: (src isRegTypeGPB | src isRegTypeGPW | src isRegTypeGPD | src isRegTypeGPQ ).
+        ^ emitter emitX86RM: 16r88 + src isRegTypeGPB not asBit
+            size: src size regOrCode: src rm: dst
+    ].
+
+    "mem <- imm"
+    dst isMem & src isImm ifTrue: [ | immSize |
+        
+        immSize := dst size <= 4 ifTrue: [ dst size ] ifFalse: [4].
+        
+        emitter emitX86RM: 16rC6 + ((dst size = 1) not) asBit
+            size: dst size 
+            regOrCode:  0 rm:  dst 
+            immSize: immSize.
+        
+        ^ emitter emitImmediate: src size: immSize
+    ].
+
+    self invalidInstruction 
+!
+
+emitmovPtr: emitter operand1: op1 operand2: op2 operand3: op3
+
+    | reg imm opCode |
+    (op1 isReg & op2 isImm) | (op1 isImm & op2 isReg) ifFalse: [
+        self invalidInstruction ].
+    
+    opCode := op1 isReg 
+        ifTrue: [reg := op1. imm := op2. 16rA0] 
+        ifFalse: [reg := op2. imm := op1. 16rA2].
+    
+    reg index ~= 0 ifTrue: [ self invalidInstruction ].
+
+    reg isRegTypeGPW ifTrue: [ emitter emitByte: 16r66 ].
+
+    emitter emitRexR: (reg size=8) opReg: 0 regCode: 0.
+    emitter emitByte: opCode + (reg size ~=1) asBit.
+    emitter emitImmediate: imm size: reg size
+!
+
+emitmovSxZx: emitter operand1: dst operand2: src operand3: op3
+
+    dst isReg & src isRegMem ifFalse: [ self invalidInstruction ].
+    
+    dst isRegTypeGPB ifTrue: [ self invalidInstruction ].
+    
+    (src size ~= 2 and: [src size ~= 1 ]) ifTrue: [ self invalidInstruction ].
+    (src size = 2 and: [dst isRegTypeGPW ]) ifTrue: [ self invalidInstruction ].
+    
+    src size = 2 ifTrue: [
+        ^ emitter emitX86RM: opCode1 + 1 size: dst size regOrCode: dst rm: src
+        ].
+    
+    emitter emitX86RM: opCode1 size: dst size regOrCode: dst rm: src
+!
+
+emitmovbe: anAJx86Assembler operand1: anUndefinedObject operand2: anUndefinedObject3 operand3: anUndefinedObject4 
+    self shouldBeImplemented
+!
+
+emitmovsxd: emitter operand1: dst operand2: src operand3: op3
+
+    emitter is64BitMode ifFalse: [ self invalidInstruction ].
+    dst isReg & src isRegMem ifFalse: [ self invalidInstruction ].
+    
+    emitter emitX86RM: 16r63 
+        size: dst size
+        regOrCode: dst  rm: src
+!
+
+emitpop: emitter operand1: op1 operand2: op2 operand3: op3
+
+    op1 isReg ifTrue: [
+        (op1 isRegTypeGPW | (emitter isGPNRegister: op1)) 
+            ifFalse: [ self error: 'Invalid register given: ', op1 asString].
+        ^ emitter emitX86Inl: opCode1 reg: op1.
+        ].
+    
+    op1 isMem ifFalse: [ self invalidInstruction ].
+    emitter emitX86RM: opCode2 size: op1 size regOrCode: opCodeR rm: op1
+!
+
+emitpush: emitter operand1: op1 operand2: op2 operand3: op3
+
+    "This section is only for immediates, memory/register operands are handled in emitpop:..."
+    op1 isImm ifTrue: [
+        op1 isInt8 & (op1 relocMode == #RelocNone) ifTrue: [
+            emitter emitByte: 16r6A.
+            ^ emitter emitImmediate: op1 size: 1 ].
+        
+        emitter emitByte: 16r68.
+        ^ emitter emitImmediate: op1 size: 4
+        ].
+    
+    ^ self emitpop: emitter operand1: op1 operand2: op2 operand3: op3
+!
+
+emitret: emitter operand1: op1 operand2: op2 operand3: op3
+
+    op1 ifNil: [ ^ emitter emitByte: 16rC3 ].
+    
+    op1 isImm ifFalse: [ self invalidInstruction ].
+    
+    self assert: (op1 isUnsigned and: [op1 fitsInSize: 2]).
+    
+    (op1 value = 0 and: [ op1 relocMode  == #RelocNone ]) ifTrue: [
+        ^ emitter emitByte: 16rC3	].
+        
+    emitter emitByte: 16rC2.
+    emitter emitImmediate: op1 size: 2
+!
+
+emitrm: emitter operand1: dst operand2: src operand3: op3
+
+    emitter emitX86RM: opCode1 + (dst isRegTypeGPB not) asBit
+        size: dst size
+        regOrCode: opCodeR rm: dst
+!
+
+emitrmr: emitter operand1: dst operand2: src operand3: op3
+
+    dst isRegMem & src isReg ifFalse: [ self invalidInstruction ].
+    
+    emitter emitX86RM: opCode1 + (src isRegTypeGPB not) asBit
+        size: src size
+        regOrCode: src rm: dst
+!
+
+emitrot: emitter operand1: op1 operand2: op2 operand3: op3
+    | useImm8 opCode |
+    op1 isRegMem & ((op2 isRegTypeGPB and: [ op2 index =  1 "cl" ]) | op2 isImm) ifFalse: [ self invalidInstruction ].
+    
+    useImm8 := op2 isImm and: [ (op2 value ~= 1) | (op2 relocMode ~~ #RelocNone) ].
+    opCode := useImm8 ifTrue: [ 16rC0 ] ifFalse: [ 16rD0 ].
+
+    op1 size ~= 1 ifTrue: [ opCode := opCode bitOr: 1 ].
+    op2 isReg ifTrue: [ opCode := opCode bitOr: 2 ].
+    
+    emitter emitX86RM: opCode
+        size: op1 size
+        regOrCode: opCodeR
+        rm: 	op1
+        immSize: useImm8 asBit.
+    
+    useImm8 ifTrue: [
+        emitter emitImmediate: op2 size: 1
+        ]
+!
+
+emitrrm: emitter operand1: dst operand2: src operand3: op3
+
+    dst isReg & src isRegMem ifFalse: [ self invalidInstruction ].
+    
+    self assert: (dst isRegTypeGPB not).
+    
+    emitter emitX86RM: opCode1
+        size: dst size
+        regOrCode: dst rm: src
+!
+
+emitshldShrd: emitter operand1: dst operand2: src1 operand3: src2
+
+    (src2 isImm or: [ src2 isRegTypeGPB and: [ src2 index = 1 "cl"]]) ifFalse: [ self invalidInstruction ].
+    
+    dst isRegMem & src1 isReg ifFalse: [ self invalidInstruction ].
+    self assert: (dst size = src1 size).
+    
+    emitter emitX86RM: opCode1 + src2 isReg asBit
+        size: src1 size
+        regOrCode: src1 rm: dst immSize: src2 isImm asBit.
+        
+    src2 isImm ifTrue: [
+        emitter emitImmediate: src2 size: 1
+        ]
+!
+
+emitx87addp: emitter operand1: op1 operand2: op2 operand3: op3
+
+    | opp |
+    opp := op1 ifNil:  [ AJx87Register new code: 1 ].
+    
+    opp isRegTypeX87 ifTrue: [
+        emitter emitByte: (opCode1 bitAnd: 16rFF00)>>8.
+        emitter emitByte: (opCode1 bitAnd: 16rFF)
+            + opp index.
+        ^ self 
+    ].
+
+    ^self emitx87sti: emitter operand1: opp operand2: op2 operand3: op3
+    
+!
+
+emitx87fpu: emitter operand1: op1 operand2: op2 operand3: op3 
+    "Either we are in memory, and carry out by using D8 / DC followed by modRM where reg indicates the operation"
+    op1 isMem 
+        ifTrue: [
+        (op2 notNil or: [op3]) notNil ifTrue: [self error: 'Invalid arguments!!'].
+        
+        emitter emitByte: (opCode1 >> (32 - (op1 size* 2)) bitAnd: 16rFF).
+        ^op1 emitModRM: emitter code: opCodeR immSize: nil].
+    "Or both my arguments are X87 registers, one of which is ST0.
+    Store in op1 register."
+    (op1 isRegTypeX87 and: [op2 isRegTypeX87]) ifTrue: [|shift offset|
+        op1 index = 0 
+            ifTrue: [shift := 24.
+                    offset := op2 index]
+            ifFalse: [
+            op2 index = 0 
+                ifTrue: [shift = 16.
+                    offset := op1 index]
+                ifFalse: [self error: 'ST0 must be one of arguments']].
+
+        "D8 if Storing in ST0, DC if storing in other"
+        emitter emitByte: (opCode1 >> shift bitAnd: 16rFF).
+    
+        emitter emitByte: (opCode1 >> (shift - 16) bitAnd: 16rFF) + offset
+        ]
+        ifFalse: [self error: 'Invalid arguments!!']
+    
+!
+
+emitx87fstsw: anAJx86Assembler operand1: anUndefinedObject operand2: anUndefinedObject3 operand3: anUndefinedObject4 
+    self shouldBeImplemented
+!
+
+emitx87mem: emitter operand1: m operand2: op2 operand3: op3
+    | opCode mod |
+      m isMem ifFalse: [ ^ self invalidInstruction ].
+
+    opCode := mod := 0.
+
+    (m is16 and: [ (o1Flags bitAnd: OFM2) ~= 0 ]) ifTrue: [
+        opCode := (opCode1 bitAnd: 16rFF000000) >> 24.
+        mod := opCodeR ].
+
+    (m is32 and: [ (o1Flags bitAnd: OFM4) ~= 0 ]) ifTrue: [
+        opCode := (opCode1 bitAnd: 16r00FF0000) >> 16.
+        mod := opCodeR ].
+    
+    (m is64 and: [ (o1Flags bitAnd: OFM8) ~= 0 ]) ifTrue: [
+        opCode := (opCode1 bitAnd: 16r0000FF00) >> 8.
+        mod :=  (opCode1 bitAnd: 16r000000FF) ].
+
+    opCode = 0 ifTrue: [ self invalidInstruction ].
+
+    emitter emitSegmentPrefix: m;
+        emitByte: opCode.
+    m emitModRM: emitter code: mod immSize: 0.
+!
+
+emitx87memSti: emitter operand1: op1 operand2: op2 operand3: op3
+
+    op1 isRegTypeX87 ifTrue: [
+        emitter emitByte: (opCode2 bitAnd: 16rFF000000)>>24.
+        emitter emitByte: (opCode2 bitAnd: 16r00FF0000)>>16
+            + op1 index.
+        ^ self 
+    ].
+
+      " ... fall through to I_X87_MEM ... "
+
+    ^ self emitx87mem: emitter operand1: op1 operand2: op2 operand3: op3
+!
+
+emitx87sti: emitter operand1: op1 operand2: op2 operand3: op3
+    (op1 isNil and: [ op2 isNil and: [ op3 isNil ]])
+        ifTrue: [ "Convenience fallback for ST1 "
+            ^ self emitx87sti: emitter operand1: AJx86Registers ST1 operand2: nil operand3: nil ].
+        
+    op1 isRegTypeX87 ifTrue: [
+        emitter emitByte: (opCode1 bitAnd: 16rFF00)>>8.
+        emitter emitByte: (opCode1 bitAnd: 16rFF) + op1 index.
+        ^ self 
+    ].
+
+    self invalidInstruction
+!
+
+emitxchg: emitter operand1: dst operand2: src operand3: op3
+
+    dst isRegMem & src isReg ifFalse: [ self invalidInstruction ].
+    
+    emitter emitSizePrefix: src segment: dst.
+    
+    "Special opcode for index 0 registers (AX, EAX, RAX vs register)"
+    dst isReg & (dst size > 1) & (dst index =0 or: [ src index = 0 ] ) ifTrue: [
+            | index |
+            index := dst index + src index.
+            ^ emitter emitByte: 16r90 + index.
+        ].
+    
+    emitter emitByte: 16r86 + src isRegTypeGPB not asBit.
+    dst emitModRM: emitter code: src code immSize: 0
+! !
+
+!AJx86InstructionDescription methodsFor:'emitting-dispatch'!
+
+emitUsing: emitter operand1: op1 operand2: op2 operand3: op3
+
+    (self is64BitOnly and: [ emitter is64BitMode not ]) ifTrue: [ 
+        self error: 'instruction is only for 64 bit mode' ].
+
+    (self is32BitOnly and: [ emitter is32BitMode not ]) ifTrue: [ 
+        self error: 'instruction is only for 32 bit mode' ].
+
+    
+    ^ self perform: groupEmitSelector withArguments: 	{ emitter. op1. op2. op3 }
+!
+
+emitUsing: emitter operands: operands
+    |args|
+    
+    (self is64BitOnly and: [ emitter is64BitMode not ]) ifTrue: [ 
+        self error: 'instruction ', self name asUppercase,' is only for 64 bit mode' ].
+
+    (self is32BitOnly and: [ emitter is32BitMode not ]) ifTrue: [ 
+        self error: 'instruction ', self name asUppercase,' is only for 32 bit mode' ].
+    
+    "manually create the arguments array"
+    args := Array new: 4.
+    args at: 1 put: emitter.
+    args replaceFrom: 2
+        to: (operands size + 1 min: 4)
+        with: operands
+        startingAt: 1.
+        
+    ^ self 
+        perform: groupEmitSelector 
+        withArguments: args
+! !
+
+!AJx86InstructionDescription methodsFor:'errors'!
+
+invalidInstruction
+    self error: 'invalid instruction'
+! !
+
+!AJx86InstructionDescription methodsFor:'initialize-release'!
+
+fromArray: arr
+    | tmp |
+    name := arr at: 1.
+    group := arr at: 2.
+    groupEmitSelector := ('emit', group,':operand1:operand2:operand3:') asSymbol.
+    
+    tmp := arr at: 3.
+    tmp isSymbol ifTrue: [ tmp := self translateSymFlag: tmp ].
+    o1Flags := tmp.
+    o2Flags := arr at: 4.
+    opCodeR := arr at: 5.
+    opCode1 := arr at: 6.
+    opCode2 := arr at: 7.
+!
+
+translateSymFlag: aflag
+
+    " 64-bit mode only instruction "
+    aflag == #x64 ifTrue: [ ^ 2r100000000 ].
+
+    " 32-bit mode only instruction "
+    aflag == #x86 ifTrue: [ ^ 2r1000000000 ].
+
+    self error: 'unknown flag'.
+! !
+
+!AJx86InstructionDescription methodsFor:'printing'!
+
+printDWord: value
+
+    | str |
+    str := value printStringBase: 16.
+    
+    [str size < 8] whileTrue: [ str:= '0',str ].
+
+    ^ '16r', str
+!
+
+printOn: aStream
+
+    aStream nextPutAll: '(';
+    nextPutAll: name printString;
+    space;
+    nextPutAll: group printString;
+    space.
+
+    "print o1Flags"
+    o1Flags > 0 ifTrue: [ aStream nextPutAll: '"op1" 2r' , (o1Flags printStringBase: 2) ]
+        ifFalse: [ aStream nextPutAll: '0'].
+    aStream space.
+    
+    "print o2Flags"
+    o2Flags > 0 ifTrue: [ aStream nextPutAll: '"op2" 2r' , (o2Flags printStringBase: 2) ]
+        ifFalse: [ aStream nextPutAll: '0'].
+    aStream space.
+
+    "print opCodeR"
+    aStream nextPutAll: '"R" '.
+    opCodeR printOn: aStream.
+    aStream space.
+    
+    "print opCode1"
+    opCode1 > 0 ifTrue: [ 
+        aStream nextPutAll: '"C1" '.
+        aStream nextPutAll:  (self printDWord: opCode1 ) ]
+        ifFalse: [ aStream nextPutAll: '0'].
+        
+    aStream space.
+
+    "print opCode2"
+    opCode2 > 0 ifTrue: [ 
+        aStream nextPutAll: '"C2" '.
+        aStream nextPutAll:  (self printDWord: opCode2 ) ]
+        ifFalse: [ aStream nextPutAll: '0'].
+
+    aStream space;
+    nextPut: $) 
+    
+! !
+
+!AJx86InstructionDescription methodsFor:'testing'!
+
+is32BitOnly
+    ^ (o1Flags bitAnd: 2r1000000000) ~= 0
+!
+
+is64BitOnly
+    ^ (o1Flags bitAnd: 2r100000000) ~= 0
+!
+
+isJump
+
+    ^ group == #cjmp or: [ group == #jmp ]
+! !
+
+
+AJx86InstructionDescription initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx86JumpInstruction.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,124 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJJumpInstruction subclass:#AJx86JumpInstruction
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-x86-Instructions'
+!
+
+AJx86JumpInstruction comment:''
+!
+
+
+!AJx86JumpInstruction methodsFor:'accessing'!
+
+codeSize 
+    machineCode ifNil: [  ^ 2 ].
+    ^ machineCode size
+!
+
+instructionDesciptions
+    ^ AJx86InstructionDescription instructions
+!
+
+machineCodeSize
+
+    machineCode ifNil: [ ^ 2 ].
+    
+    ^ machineCode size
+! !
+
+!AJx86JumpInstruction methodsFor:'convenience'!
+
+errorUndefinedLabel: aLabel 
+
+    ^ self error: 'undefined label: ', aLabel name
+! !
+
+!AJx86JumpInstruction methodsFor:'emitting code'!
+
+emitCode: asm
+    "generate opcodes"
+
+    | delta code nextInstruction target desc |
+    
+    target := label position.
+    target ifNil: [ ^ machineCode := nil ].
+    
+    nextInstruction := position + 2.
+    delta := (target - nextInstruction) asImm.
+    desc := self instructionDesciptions at: name.	"can we use 8bit offset?"
+    machineCode := delta isInt8
+        ifTrue: [ 	self emitShortJump: desc offset: delta ]
+        ifFalse: [ self emitLongJump: desc target: target ]
+!
+
+emitCodeAtOffset: offset assembler: asm
+    
+    position := offset.
+    [ | labelPos | 
+        labelPos := label position.
+        labelPos ifNotNil: [ self emitCode: asm ].
+        next ifNotNil: [ 
+            next emitCodeAtOffset: offset + self machineCodeSize assembler: asm ].
+        label position ~= labelPos ] whileTrue.
+    
+    label position ifNil: [ self errorUndefinedLabel: label  ]
+!
+
+emitConditionalJump: addr to: desc
+    ^ {16r0F.
+    (16r80 + desc opCode1).
+    (addr bitAnd: 255).
+    (addr >> 8 bitAnd: 255).
+    (addr >> 16 bitAnd: 255).
+    (addr >> 24 bitAnd: 255)} asByteArray
+!
+
+emitLongJump: desc target: target
+    | addr sz nextInstruction |
+    
+    sz := self isConditional
+        ifTrue: [ 2 ]
+        ifFalse: [ 1 ].
+        
+    nextInstruction := position + 4 + sz.
+    addr := (AJImmediate ivalue: target - nextInstruction) asDWord.
+    
+    ^ self isConditional
+        ifFalse: [ self emitUnconditionalJumpTo: addr ]
+        ifTrue: [ 	self emitConditionalJump: addr to: desc ]
+!
+
+emitShortJump: desc offset: delta
+    "short jump"
+    ^ self isConditional
+        ifTrue: [ {(16r70 + desc opCode1). (delta asByte)} asByteArray ]
+        ifFalse: [ {16rEB. (delta asByte)} asByteArray ]
+!
+
+emitUnconditionalJumpTo: addr
+    ^ {
+    16rE9.
+    (addr bitAnd: 255).
+    (addr >> 8 bitAnd: 255).
+    (addr >> 16 bitAnd: 255).
+    (addr >> 24 bitAnd: 255)} asByteArray
+! !
+
+!AJx86JumpInstruction methodsFor:'testing'!
+
+isConditional
+    ^ name ~~ #jmp
+! !
+
+!AJx86JumpInstruction class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx86RegisterTests.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,165 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+TestCase subclass:#AJx86RegisterTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:'AJx86Registers'
+	category:'AsmJit-Tests'
+!
+
+AJx86RegisterTests comment:''
+!
+
+!AJx86RegisterTests methodsFor:'as yet unclassified'!
+
+testAsHighByte
+    | highByteRegs lowByteRegs otherGPRegs |
+    highByteRegs := {AH.
+    CH.
+    DH.
+    BH}.
+    lowByteRegs := {AL.
+    CL.
+    DL.
+    BL}.
+    otherGPRegs := AJx86Registers generalPurpose reject: [ :r | r isHighByte | r isLowByte ].
+    self assert: (highByteRegs collect: [ :r | r asHighByte ]) equals: highByteRegs.
+    self assert: (lowByteRegs collect: [ :r | r asHighByte ]) equals: highByteRegs.
+    self assert: otherGPRegs size equals: 60.	"16 of each size, less the lowByteRegs"
+    otherGPRegs do: [ :r | self should: [ r asHighByte ] raise: Error ]
+!
+
+testAsLowByte
+    | highByteRegs lowByteRegs otherGPRegs |
+    highByteRegs := {AH.
+    CH.
+    DH.
+    BH}.
+    lowByteRegs := {AL.
+    CL.
+    DL.
+    BL}.
+    otherGPRegs := AJx86Registers generalPurpose reject: [ :r | r isHighByte | r isLowByte ].
+    self assert: (highByteRegs collect: [ :r | r asLowByte ]) equals: lowByteRegs.
+    self assert: (lowByteRegs collect: [ :r | r asLowByte ]) equals: lowByteRegs.
+    self assert: otherGPRegs size equals: 60.	"16 of each size, less the lowByteRegs"
+    otherGPRegs do: [ :r | self should: [ r asLowByte ] raise: Error ]
+!
+
+testRegisterWidthConversions
+    "Test the generalPurpose register methods #as8, #as16, #as32, #as64. 
+    Some resulting registers are not valid except in 64-bit mode, but that is not checked until you try to use the register in an instruction."
+
+    | regs8 regs16 regs32 regs64 highByteRegs |
+    regs8 := {AL.
+    CL.
+    DL.
+    BL.
+    SPL.
+    BPL.
+    SIL.
+    DIL.
+    R8B.
+    R9B.
+    R10B.
+    R11B.
+    R12B.
+    R13B.
+    R14B.
+    R15B}.
+    regs16 := {AX.
+    CX.
+    DX.
+    BX.
+    SP.
+    BP.
+    SI.
+    DI.
+    R8W.
+    R9W.
+    R10W.
+    R11W.
+    R12W.
+    R13W.
+    R14W.
+    R15W}.
+    regs32 := {EAX.
+    ECX.
+    EDX.
+    EBX.
+    ESP.
+    EBP.
+    ESI.
+    EDI.
+    R8D.
+    R9D.
+    R10D.
+    R11D.
+    R12D.
+    R13D.
+    R14D.
+    R15D}.
+    regs64 := {RAX.
+    RCX.
+    RDX.
+    RBX.
+    RSP.
+    RBP.
+    RSI.
+    RDI.
+    R8.
+    R9.
+    R10.
+    R11.
+    R12.
+    R13.
+    R14.
+    R15}.
+    highByteRegs := {AH.
+    CH.
+    DH.
+    BH}.
+    self
+        assert: (regs8 collect: [ :r | r as8 ]) equals: regs8;
+        assert: (regs16 collect: [ :r | r as8 ]) equals: regs8;
+        assert: (regs32 collect: [ :r | r as8 ]) equals: regs8;
+        assert: (regs64 collect: [ :r | r as8 ]) equals: regs8.
+    self
+        assert: (regs8 collect: [ :r | r as16 ]) equals: regs16;
+        assert: (regs16 collect: [ :r | r as16 ]) equals: regs16;
+        assert: (regs32 collect: [ :r | r as16 ]) equals: regs16;
+        assert: (regs64 collect: [ :r | r as16 ]) equals: regs16.
+    self
+        assert: (regs8 collect: [ :r | r as32 ]) equals: regs32;
+        assert: (regs16 collect: [ :r | r as32 ]) equals: regs32;
+        assert: (regs32 collect: [ :r | r as32 ]) equals: regs32;
+        assert: (regs64 collect: [ :r | r as32 ]) equals: regs32.
+    self
+        assert: (regs8 collect: [ :r | r as64 ]) equals: regs64;
+        assert: (regs16 collect: [ :r | r as64 ]) equals: regs64;
+        assert: (regs32 collect: [ :r | r as64 ]) equals: regs64;
+        assert: (regs64 collect: [ :r | r as64 ]) equals: regs64.
+    self
+        assert: (highByteRegs collect: [ :r | r as8 ]) equals: highByteRegs;
+        assert: (highByteRegs collect: [ :r | r as16 ])
+            equals:
+                {AX.
+                    CX.
+                    DX.
+                    BX};
+        assert: (highByteRegs collect: [ :r | r as32 ])
+            equals:
+                {EAX.
+                    ECX.
+                    EDX.
+                    EBX};
+        assert: (highByteRegs collect: [ :r | r as64 ])
+            equals:
+                {RAX.
+                    RCX.
+                    RDX.
+                    RBX}
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx86Registers.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,880 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+SharedPool subclass:#AJx86Registers
+	instanceVariableNames:''
+	classVariableNames:'AH AL AX BH BL BP BPL BX CH CL CX Codes DH DI DIL DL DX EAX EBP
+		EBX ECX EDI EDX EIP ESI ESP IP MM0 MM1 MM2 MM3 MM4 MM5 MM6 MM7
+		R10 R10B R10D R10W R11 R11B R11D R11W R12 R12B R12D R12W R13 R13B
+		R13D R13W R14 R14B R14D R14W R15 R15B R15D R15W R8 R8B R8D R8W R9
+		R9B R9D R9W RAX RBP RBX RCX RDI RDX RIP RSI RSP SI SIL SP SPL ST0
+		ST1 ST2 ST3 ST4 ST5 ST6 ST7 XMM0 XMM1 XMM10 XMM11 XMM12 XMM13
+		XMM14 XMM15 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 XMM9'
+	poolDictionaries:'AJConstants'
+	category:'AsmJit-x86'
+!
+
+AJx86Registers comment:'I am a SHaredPool which initializes all the registers needed by the Assmbler.'
+!
+
+!AJx86Registers class methodsFor:'initialization'!
+
+initialize
+    "AJx86Registers initialize"
+        
+    self classPool at: #Codes put: IdentityDictionary new. 
+    
+    self initializeGeneralPurpose8BitRegisters.
+    self initializeGeneralPurpose16BitRegisters.
+    self initializeGeneralPurpose32BitRegisters.
+    self initializeGeneralPurpose64BitRegisters.
+    
+    self initializeInstructionPointerRegisters.
+    
+    self initializeX87Registers.
+    self initializeMMXRegisters.
+    self initializeSSERegisters.
+!
+
+initializeGeneralPurpose16BitRegisters
+    "initialize general purpose 16 bit registers "
+
+    self
+        registerBase: 16r10
+            class: AJx86GPRegister
+            rex: #dontCare
+            values: #(#AX #CX #DX #BX #SP #BP #SI #DI);
+        registerBase: 16r18
+            class: AJx86GPRegister
+            rex: #required
+            values: #(#R8W #R9W #R10W #R11W #R12W #R13W #R14W #R15W)
+!
+
+initializeGeneralPurpose32BitRegisters
+    "initialize general purpose 32 bit registers "
+
+    self
+        registerBase: 16r20
+            class: AJx86GPRegister
+            rex: #dontCare
+            values: #(#EAX #ECX #EDX #EBX #ESP #EBP #ESI #EDI);
+        registerBase: 16r28
+            class: AJx86GPRegister
+            rex: #required
+            values: #(#R8D #R9D #R10D #R11D #R12D #R13D #R14D #R15D)
+!
+
+initializeGeneralPurpose64BitRegisters
+    "initialize general purpose 64 bit registers"
+    
+    self
+        registerBase: 16r30
+            class: AJx86GPRegister
+            rex: #dontCare
+            values: #(#RAX #RCX #RDX #RBX #RSP #RBP #RSI #RDI);
+        registerBase: 16r38
+            class: AJx86GPRegister
+            rex: #required
+            values: #(#R8 #R9 #R10 #R11 #R12 #R13 #R14 #R15)
+!
+
+initializeGeneralPurpose8BitRegisters
+    "general purpose 8 bit registers "
+
+    self
+        registerBase: 0
+            class: AJx86GPRegister
+            rex: #dontCare
+            values: #(#AL #CL #DL #BL);
+        registerBase: 4
+            class: AJx86GPRegister
+            rex: #prohibited
+            values: #(#AH #CH #DH #BH);
+        registerBase: 4
+            class: AJx86GPRegister
+            rex: #required
+            values: #(#SPL #BPL #SIL #DIL #R8B #R9B #R10B #R11B #R12B #R13B #R14B #R15B)
+!
+
+initializeInstructionPointerRegisters
+    | ip eip rip |
+    
+    ip := AJx64RipRegister code: SI code name: #IP.
+    eip := AJx64RipRegister code: ESI code name: #EIP.
+    rip := AJx64RipRegister code: RSI code name: #RIP.
+    
+    Codes 
+        at: SI code negated put: #IP;
+        at: ESI code negated put: #EIP;
+        at: RSI code negated put: #RIP.
+    
+    self classPool 
+        at: #IP put: ip;
+        at: #EIP put: eip;
+        at: #RIP put: rip.
+!
+
+initializeMMXRegisters
+
+    " MMX registers "
+    self registerBase: 16r60  class: AJMMRegister values: #(
+        #MM0 #MM1   #MM2   #MM3   #MM4   #MM5   #MM6   #MM7 ).
+!
+
+initializeSSERegisters
+    " SSE registers "
+    self registerBase: 16r70 class: AJxMMRegister  values: #(
+        #XMM0 #XMM1  #XMM2  #XMM3  #XMM4  #XMM5  #XMM6  #XMM7 
+        #XMM8 #XMM9  #XMM10 #XMM11 #XMM12 #XMM13 #XMM14 #XMM15).
+!
+
+initializeX87Registers
+    "X87 registers"
+    self registerBase: 16r50 class: AJx87Register values: #(
+        #ST0 #ST1 #ST2 #ST3 #ST4 #ST5 #ST6 #ST7 ).
+!
+
+registerBase: base class: regClass rex: rexSymbol values: names 
+    | val |
+    val := 0.
+    rexSymbol == #required
+        ifTrue: [ val := 16r100 ].
+    rexSymbol == #prohibited
+        ifTrue: [ val := 16r200 ].
+    val := val + base.
+    names
+        do: [ :regName | 
+            | reg |
+            reg := regClass code: val name: regName.
+            self classPool at: regName put: reg.
+            Codes at: val put: regName.
+            val := val + 1 ]
+!
+
+registerBase: base class: regClass values: names
+
+    | val |
+    val := base.
+    names do: [ :regName | | reg |
+        reg := regClass code: val name: regName.
+        self classPool at: regName put: reg. 
+        Codes at: val put: regName.
+        val := val + 1].
+!
+
+sortRegistersByIndex: aRegisterCollection
+    ^ aRegisterCollection sort: [ :regA :regB| regA index < regB index ].
+! !
+
+!AJx86Registers class methodsFor:'accessing'!
+
+all
+    ^ Codes values collect: [ :each| self classPool at: each ]
+!
+
+all16
+    ^ self all select: [:reg| reg is16 ]
+!
+
+all32
+    ^ self all select: [:reg| reg is32 ]
+!
+
+all64
+    ^ self all select: [:reg| reg is64 ]
+!
+
+all8
+    ^ self all select: [:reg| reg is8 ]
+!
+
+at: aRegisterIdentifierSymbol
+    ^ self classPool at: aRegisterIdentifierSymbol
+!
+
+code: registerCode
+    "Access a register by its code.
+    Example:
+        RBP == (self code: RBP code)"
+    | registerName |
+    self flag: 'XXX now this is some ugly code... add an instance variable for the requiresRex boolean instead of encoding it in #code'.
+    registerName := Codes at: registerCode ifAbsent: [ 
+                Codes at: registerCode + 16r100 ifAbsent: [ 
+                    Codes at: registerCode + 16r200 ifAbsent: [  KeyNotFound signalFor: registerCode ] ] ].
+    ^ self classPool at: registerName
+!
+
+doesNotUnderstand: aMessage
+    self classPool at: aMessage selector ifPresent: [:val| ^ val ].
+    ^ super doesNotUnderstand: aMessage
+!
+
+generalPurpose
+    ^ self all select: [ :reg| reg isGeneralPurpose ]
+!
+
+generalPurpose16
+    ^ self sortRegistersByIndex: (self generalPurpose select: [:reg| reg is16 ])
+!
+
+generalPurpose32
+    ^ self sortRegistersByIndex: (self generalPurpose select: [:reg| reg is32 ])
+!
+
+generalPurpose64
+    ^ self sortRegistersByIndex: (self generalPurpose select: [:reg| reg is64 ])
+!
+
+generalPurpose8
+    ^ self sortRegistersByIndex: (self generalPurpose select: [:reg| reg is8 ])
+!
+
+generalPurposeWithIndex: index size: numBytes requiresRex: requiresRex prohibitsRex: prohibitsRex
+    "Access a register by its properties.
+    Example:
+        RBP == (self generalPurposeWithIndex: RBP index size: RBP size requiresRex: RBP requiresRex prohibitsRex: RBP prohibitsRex )"
+
+    | type code |
+    type := numBytes = 1
+        ifTrue: [ 0 ]
+        ifFalse: [ 
+            numBytes = 2
+                ifTrue: [ 16r10 ]
+                ifFalse: [ 
+                    numBytes = 4
+                        ifTrue: [ 16r20 ]
+                        ifFalse: [ 
+                            numBytes = 8
+                                ifTrue: [ 16r30 ]
+                                ifFalse: [ self error: 'Size must be 1, 2, 4, or 8 bytes' ] ] ] ].
+    code := type + index.
+    requiresRex
+        ifTrue: [ code := code + RegRequiresRexMask ].
+    prohibitsRex
+        ifTrue: [ code := code + RegProhibitsRexMask ].
+    ^ self classPool at: (Codes at: code)
+! !
+
+!AJx86Registers class methodsFor:'accessing registers'!
+
+AH
+    "A 8bit general purpose register
+    This register overlaps with AH, AX, EAX, RAX"
+    ^ self at: #AH
+!
+
+AL
+    "A 8bit general purpose register
+    This register overlaps with AL, AX, EAX, RAX"
+    ^ self at: #AL
+!
+
+AX
+    "A 16bit general purpose register
+    This register overlaps with AL, AX, EAX, RAX"
+    ^ self at: #AX
+!
+
+BH
+    "A 8bit general purpose register
+    This register overlaps with BH, BX, EBX, RBX"
+    ^ self at: #BH
+!
+
+BL
+    "A 8bit general purpose register
+    This register overlaps with BL, BX, EBX, RBX"
+    ^ self at: #BL
+!
+
+BP
+    "A 16bit general purpose register
+    This register overlaps with CH, CX, ECX, RCX"
+    ^ self at: #BP
+!
+
+BX
+    "A 16bit general purpose register
+    This register overlaps with BL, BX, EBX, RBX"
+    ^ self at: #BX
+!
+
+CH
+    "A 8bit general purpose register
+    This register overlaps with CH, CX, ECX, RCX"
+    ^ self at: #CH
+!
+
+CL
+    "A 8bit general purpose register
+    This register overlaps with CL, CX, ECX, RCX"
+    ^ self at: #CL
+!
+
+CX
+    "A 16bit general purpose register
+    This register overlaps with CL, CX, ECX, RCX"
+    ^ self at: #CX
+!
+
+DH
+    "A 8bit general purpose register
+    This register overlaps with DH, DX, EDX, RDX"
+    ^ self at: #DH
+!
+
+DI
+    "A 16bit general purpose register
+    This register overlaps with BH, BX, EBX, RBX"
+    ^ self at: #DI
+!
+
+DL
+    "A 8bit general purpose register
+    This register overlaps with DL, DX, EDX, RDX"
+    ^ self at: #DL
+!
+
+DX
+    "A 16bit general purpose register
+    This register overlaps with DL, DX, EDX, RDX"
+    ^ self at: #DX
+!
+
+EAX
+    "A 32bit general purpose register
+    This register overlaps with AL, AX, EAX, RAX"
+    ^ self at: #EAX
+!
+
+EBP
+    "A 32bit general purpose register
+    This register overlaps with CH, CX, ECX, RCX"
+    ^ self at: #EBP
+!
+
+EBX
+    "A 32bit general purpose register
+    This register overlaps with BL, BX, EBX, RBX"
+    ^ self at: #EBX
+!
+
+ECX
+    "A 32bit general purpose register
+    This register overlaps with CL, CX, ECX, RCX"
+    ^ self at: #ECX
+!
+
+EDI
+    "A 32bit general purpose register
+    This register overlaps with BH, BX, EBX, RBX"
+    ^ self at: #EDI
+!
+
+EDX
+    "A 32bit general purpose register
+    This register overlaps with DL, DX, EDX, RDX"
+    ^ self at: #EDX
+!
+
+EIP
+    "A 32bit instruction pointer register
+    This register overlaps with IP, EIP, RIP"
+    ^ self at: #EIP
+!
+
+ESI
+    "A 32bit general purpose register
+    This register overlaps with DH, DX, EDX, RDX"
+    ^ self at: #ESI
+!
+
+ESP
+    "A 32bit general purpose register
+    This register overlaps with AH, AX, EAX, RAX"
+    ^ self at: #ESP
+!
+
+IP
+    "A 16bit instruction pointer register
+    This register overlaps with IP, EIP, RIP"
+    ^ self at: #IP
+!
+
+MM0
+    "An MMX register"
+    ^ self at: #MM0
+!
+
+MM1
+    "An MMX register"
+    ^ self at: #MM1
+!
+
+MM2
+    "An MMX register"
+    ^ self at: #MM2
+!
+
+MM3
+    "An MMX register"
+    ^ self at: #MM3
+!
+
+MM4
+    "An MMX register"
+    ^ self at: #MM4
+!
+
+MM5
+    "An MMX register"
+    ^ self at: #MM5
+!
+
+MM6
+    "An MMX register"
+    ^ self at: #MM6
+!
+
+MM7
+    "An MMX register"
+    ^ self at: #MM7
+!
+
+R10
+    "A 64bit general purpose register
+    This register overlaps with R10B, R10W, R10D, R10"
+    ^ self at: #R10
+!
+
+R10B
+    "A 8bit general purpose register
+    This register overlaps with R10B, R10W, R10D, R10"
+    ^ self at: #R10B
+!
+
+R10D
+    "A 32bit general purpose register
+    This register overlaps with R10B, R10W, R10D, R10"
+    ^ self at: #R10D
+!
+
+R10W
+    "A 16bit general purpose register
+    This register overlaps with R10B, R10W, R10D, R10"
+    ^ self at: #R10W
+!
+
+R11
+    "A 64bit general purpose register
+    This register overlaps with R11B, R11W, R11D, R11"
+    ^ self at: #R11
+!
+
+R11B
+    "A 8bit general purpose register
+    This register overlaps with R11B, R11W, R11D, R11"
+    ^ self at: #R11B
+!
+
+R11D
+    "A 32bit general purpose register
+    This register overlaps with R11B, R11W, R11D, R11"
+    ^ self at: #R11D
+!
+
+R11W
+    "A 16bit general purpose register
+    This register overlaps with R11B, R11W, R11D, R11"
+    ^ self at: #R11W
+!
+
+R12
+    "A 64bit general purpose register
+    This register overlaps with R12B, R12W, R12D, R12"
+    ^ self at: #R12
+!
+
+R12B
+    "A 8bit general purpose register
+    This register overlaps with R12B, R12W, R12D, R12"
+    ^ self at: #R12B
+!
+
+R12D
+    "A 32bit general purpose register
+    This register overlaps with R12B, R12W, R12D, R12"
+    ^ self at: #R12D
+!
+
+R12W
+    "A 16bit general purpose register
+    This register overlaps with R12B, R12W, R12D, R12"
+    ^ self at: #R12W
+!
+
+R13
+    "A 64bit general purpose register
+    This register overlaps with R13B, R13W, R13D, R13"
+    ^ self at: #R13
+!
+
+R13B
+    "A 8bit general purpose register
+    This register overlaps with R13B, R13W, R13D, R13"
+    ^ self at: #R13B
+!
+
+R13D
+    "A 32bit general purpose register
+    This register overlaps with R13B, R13W, R13D, R13"
+    ^ self at: #R13D
+!
+
+R13W
+    "A 16bit general purpose register
+    This register overlaps with R13B, R13W, R13D, R13"
+    ^ self at: #R13W
+!
+
+R14
+    "A 64bit general purpose register
+    This register overlaps with R14B, R14W, R14D, R14"
+    ^ self at: #R14
+!
+
+R14B
+    "A 8bit general purpose register
+    This register overlaps with R14B, R14W, R14D, R14"
+    ^ self at: #R14B
+!
+
+R14D
+    "A 32bit general purpose register
+    This register overlaps with R14B, R14W, R14D, R14"
+    ^ self at: #R14D
+!
+
+R14W
+    "A 16bit general purpose register
+    This register overlaps with R14B, R14W, R14D, R14"
+    ^ self at: #R14W
+!
+
+R15
+    "A 64bit general purpose register
+    This register overlaps with R15B, R15W, R15D, R15"
+    ^ self at: #R15
+!
+
+R15B
+    "A 8bit general purpose register
+    This register overlaps with R15B, R15W, R15D, R15"
+    ^ self at: #R15B
+!
+
+R15D
+    "A 32bit general purpose register
+    This register overlaps with R15B, R15W, R15D, R15"
+    ^ self at: #R15D
+!
+
+R15W
+    "A 16bit general purpose register
+    This register overlaps with R15B, R15W, R15D, R15"
+    ^ self at: #R15W
+!
+
+R8
+    "A 64bit general purpose register
+    This register overlaps with R8B, R8W, R8D, R8"
+    ^ self at: #R8
+!
+
+R8B
+    "A 8bit general purpose register
+    This register overlaps with R8B, R8W, R8D, R8"
+    ^ self at: #R8B
+!
+
+R8D
+    "A 32bit general purpose register
+    This register overlaps with R8B, R8W, R8D, R8"
+    ^ self at: #R8D
+!
+
+R8W
+    "A 16bit general purpose register
+    This register overlaps with R8B, R8W, R8D, R8"
+    ^ self at: #R8W
+!
+
+R9
+    "A 64bit general purpose register
+    This register overlaps with R9B, R9W, R9D, R9"
+    ^ self at: #R9
+!
+
+R9B
+    "A 8bit general purpose register
+    This register overlaps with R9B, R9W, R9D, R9"
+    ^ self at: #R9B
+!
+
+R9D
+    "A 32bit general purpose register
+    This register overlaps with R9B, R9W, R9D, R9"
+    ^ self at: #R9D
+!
+
+R9W
+    "A 16bit general purpose register
+    This register overlaps with R9B, R9W, R9D, R9"
+    ^ self at: #R9W
+!
+
+RAX
+    "A 64bit general purpose register
+    This register overlaps with AL, AX, EAX, RAX"
+    ^ self at: #RAX
+!
+
+RBP
+    "A 64bit general purpose register
+    This register overlaps with CH, CX, ECX, RCX"
+    ^ self at: #RBP
+!
+
+RBX
+    "A 64bit general purpose register
+    This register overlaps with BL, BX, EBX, RBX"
+    ^ self at: #RBX
+!
+
+RCX
+    "A 64bit general purpose register
+    This register overlaps with CL, CX, ECX, RCX"
+    ^ self at: #RCX
+!
+
+RDI
+    "A 64bit general purpose register
+    This register overlaps with BH, BX, EBX, RBX"
+    ^ self at: #RDI
+!
+
+RDX
+    "A 64bit general purpose register
+    This register overlaps with DL, DX, EDX, RDX"
+    ^ self at: #RDX
+!
+
+RIP
+    "A 64bit instruction pointer register
+    This register overlaps with IP, EIP, RIP"
+    ^ self at: #RIP
+!
+
+RSI
+    "A 64bit general purpose register
+    This register overlaps with DH, DX, EDX, RDX"
+    ^ self at: #RSI
+!
+
+RSP
+    "A 64bit general purpose register
+    This register overlaps with AH, AX, EAX, RAX"
+    ^ self at: #RSP
+!
+
+SI
+    "A 16bit general purpose register
+    This register overlaps with DH, DX, EDX, RDX"
+    ^ self at: #SI
+!
+
+SP
+    "A 16bit general purpose register
+    This register overlaps with AH, AX, EAX, RAX"
+    ^ self at: #SP
+!
+
+ST0
+    "A floating point register"
+    ^ self at: #ST0
+!
+
+ST1
+    "A floating point register"
+    ^ self at: #ST1
+!
+
+ST2
+    "A floating point register"
+    ^ self at: #ST2
+!
+
+ST3
+    "A floating point register"
+    ^ self at: #ST3
+!
+
+ST4
+    "A floating point register"
+    ^ self at: #ST4
+!
+
+ST5
+    "A floating point register"
+    ^ self at: #ST5
+!
+
+ST6
+    "A floating point register"
+    ^ self at: #ST6
+!
+
+ST7
+    "A floating point register"
+    ^ self at: #ST7
+!
+
+XMM0
+    "An SSE register"
+    ^ self at: #XMM0
+!
+
+XMM1
+    "An SSE register"
+    ^ self at: #XMM1
+!
+
+XMM10
+    "An SSE register"
+    ^ self at: #XMM10
+!
+
+XMM11
+    "An SSE register"
+    ^ self at: #XMM11
+!
+
+XMM12
+    "An SSE register"
+    ^ self at: #XMM12
+!
+
+XMM13
+    "An SSE register"
+    ^ self at: #XMM13
+!
+
+XMM14
+    "An SSE register"
+    ^ self at: #XMM14
+!
+
+XMM15
+    "An SSE register"
+    ^ self at: #XMM15
+!
+
+XMM2
+    "An SSE register"
+    ^ self at: #XMM2
+!
+
+XMM3
+    "An SSE register"
+    ^ self at: #XMM3
+!
+
+XMM4
+    "An SSE register"
+    ^ self at: #XMM4
+!
+
+XMM5
+    "An SSE register"
+    ^ self at: #XMM5
+!
+
+XMM6
+    "An SSE register"
+    ^ self at: #XMM6
+!
+
+XMM7
+    "An SSE register"
+    ^ self at: #XMM7
+!
+
+XMM8
+    "An SSE register"
+    ^ self at: #XMM8
+!
+
+XMM9
+    "An SSE register"
+    ^ self at: #XMM9
+! !
+
+!AJx86Registers class methodsFor:'method compilation'!
+
+installRegister: register accessorCategory: registerAccessorsCategory
+
+    ^ self class
+        compile:(String streamContents: [ :s | 
+            s nextPutAll: register name; crtab.
+            self printRegister: register descriptionOn: s.
+            s crtab; nextPutAll: '^ self at: #'; nextPutAll: register name ])
+        classified: registerAccessorsCategory
+!
+
+installRegister: register accessorCategory: registerAccessorsCategory on: aClass
+    
+    aClass 
+        compile: (String	streamContents: [ :s | 
+            s nextPutAll: register name; crtab.
+            self printRegister: register descriptionOn: s.
+            s crtab; nextPutAll: '^ '; nextPutAll: register name ])
+        classified: registerAccessorsCategory 
+!
+
+installRegisterAccessors
+    "this method creates simple accessors for all registers"
+
+    | registerAccessorsCategory |
+    
+    registerAccessorsCategory := 'accessing registers'.	
+    
+    "remove all methods in the 'accessing register' category"
+    self class methodDict values
+        select: [ :method | method category = registerAccessorsCategory ]
+        thenDo: [ :method | self class removeSelector: method selector ].
+        
+    self all 
+        do: [ :register | | method |
+            "install the direct accessor on this class"
+            self installRegister: register accessorCategory: registerAccessorsCategory.
+            "install the accessor on the assembler"
+            self 
+                installRegister: register 
+                accessorCategory: registerAccessorsCategory
+                on: (register isX86 ifTrue: [ AJx86Assembler ]  ifFalse: [ AJx64Assembler ])]
+        displayingProgress: [ :each| each name ].
+!
+
+printRegister: register descriptionOn: s
+
+    s nextPut: $".
+    register descriptionOn: s.
+    register influencingRegisters ifNotEmpty: [ :registers|
+        s crtab nextPutAll: 'This register overlaps with '.
+        registers do: [ :reg| s nextPutAll: reg name ] separatedBy: [ s nextPutAll: ', ']].
+    s nextPut: $"
+! !
+
+
+AJx86Registers initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJx87Register.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,47 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJBaseReg subclass:#AJx87Register
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-x86-Operands'
+!
+
+AJx87Register comment:'I am an x87 Floating Point register (ST0 - ST7) used in the FPU stack. 

The lower 64bit of the floating point ST registers are shared with the MMX registers.'
+!
+
+!AJx87Register methodsFor:'accessing'!
+
+code: aCode
+
+    code := aCode bitOr: RegX87.
+    size := 10.
+!
+
+influencingRegisters
+    "ST registers overlap with the MMX register"
+    self shouldBeImplemented.
+! !
+
+!AJx87Register methodsFor:'printing'!
+
+descriptionOn: s
+    s nextPutAll: 'A floating point register'.
+! !
+
+!AJx87Register methodsFor:'testing'!
+
+isGeneralPurpose
+    ^ false
+!
+
+isRegTypeX87
+    ^ true
+!
+
+isX86
+    ^ true
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/AJxMMRegister.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,43 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+AJBaseReg subclass:#AJxMMRegister
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'AsmJit-x86-Operands'
+!
+
+AJxMMRegister comment:'I am a register used by the SSE (Streaming SIMD Extensions) for the x86 instruction set. The independent XMM registers are 128bit wide and do not overlap with any other existing registers.

Depending on the instructions used the XMM registers represent different data types:
	SSE:  4 x 32bit single precision floats
	SSE2: 2 x 64bit double prexision floats
	      2 x 64bit integers
	      4 x 32bit integers
	      8 x 16bit short integers
	      16 x 8bit bytes/characters'
+!
+
+!AJxMMRegister methodsFor:'accessing'!
+
+code: aCode
+
+    code := aCode.
+    size := 16
+! !
+
+!AJxMMRegister methodsFor:'printing'!
+
+descriptionOn: s
+    
+    s nextPutAll: 'An SSE register'.
+! !
+
+!AJxMMRegister methodsFor:'testing'!
+
+isGeneralPurpose
+    ^ false
+!
+
+isRegTypeXMM
+    ^ true
+!
+
+isX86
+    ^ self index < 8
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/Make.proto	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,168 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: jv_dragonfly_asm.
+#
+# Warning: once you modify this file, do not rerun
+# stmkmp or projectDefinition-build again - otherwise, your changes are lost.
+#
+# The Makefile as generated by this Make.proto supports the following targets:
+#    make         - compile all st-files to a classLib
+#    make clean   - clean all temp files
+#    make clobber - clean all
+#
+# This file contains definitions for Unix based platforms.
+# It shares common definitions with the win32-make in Make.spec.
+
+#
+# position (of this package) in directory hierarchy:
+# (must point to ST/X top directory, for tools and includes)
+TOP=../../../stx
+INCLUDE_TOP=$(TOP)/..
+
+# subdirectories where targets are to be made:
+SUBDIRS=
+
+
+# subdirectories where Makefiles are to be made:
+# (only define if different from SUBDIRS)
+# ALLSUBDIRS=
+
+REQUIRED_SUPPORT_DIRS=
+
+# if your embedded C code requires any system includes,
+# add the path(es) here:,
+# ********** OPTIONAL: MODIFY the next lines ***
+# LOCALINCLUDES=-Ifoo -Ibar
+LOCALINCLUDES= -I$(INCLUDE_TOP)/stx/goodies/sunit -I$(INCLUDE_TOP)/stx/libbasic
+
+
+# if you need any additional defines for embedded C code,
+# add them here:,
+# ********** OPTIONAL: MODIFY the next lines ***
+# LOCALDEFINES=-Dfoo -Dbar -DDEBUG
+LOCALDEFINES=
+
+LIBNAME=libjv_dragonfly_asm
+STCLOCALOPT='-package=$(PACKAGE)' -I. $(LOCALINCLUDES) $(STCLOCALOPTIMIZATIONS) $(STCWARNINGS) $(LOCALDEFINES) -headerDir=.  -varPrefix=$(LIBNAME)
+
+
+# ********** OPTIONAL: MODIFY the next line ***
+# additional C-libraries that should be pre-linked with the class-objects
+LD_OBJ_LIBS=
+LOCAL_SHARED_LIBS=
+
+
+# ********** OPTIONAL: MODIFY the next line ***
+# additional C targets or libraries should be added below
+LOCAL_EXTRA_TARGETS=
+
+OBJS= $(COMMON_OBJS) $(UNIX_OBJS)
+
+
+
+all:: preMake classLibRule postMake
+
+pre_objs::  
+
+
+
+
+
+
+# Enforce recompilation of package definition class if Mercurial working
+# copy state changes. Together with --guessVersion it ensures that package
+# definition class always contains correct binary revision string.
+ifneq (**NOHG**, $(shell hg root 2> /dev/null || echo -n '**NOHG**'))
+jv_dragonfly_asm.$(O): $(shell hg root)/.hg/dirstate
+endif
+
+
+
+
+# run default testsuite for this package
+test: $(TOP)/goodies/builder/reports
+	$(MAKE) -C $(TOP)/goodies/builder/reports -f Makefile.init
+	$(TOP)/goodies/builder/reports/report-runner.sh -D . -r Builder::TestReport -p $(PACKAGE)
+
+
+
+# add more install actions here
+install::
+
+# add more install actions for aux-files (resources) here
+installAux::
+
+# add more preMake actions here
+preMake::
+
+# add more postMake actions here
+postMake:: cleanjunk
+
+# build all mandatory prerequisite packages (containing superclasses) for this package
+prereq:
+	cd $(TOP)/libbasic && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+
+
+
+# build all packages containing referenced classes for this package
+# they are not needed to compile the package (but later, to load it)
+references:
+
+
+cleanjunk::
+	-rm -f *.s *.s2
+
+clean::
+	-rm -f *.o *.H
+
+clobber:: clean
+	-rm -f *.so *.dll
+
+
+# BEGINMAKEDEPEND --- do not remove this line; make depend needs it
+$(OUTDIR)AJAssembler.$(O) AJAssembler.$(H): AJAssembler.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJCallInfo.$(O) AJCallInfo.$(H): AJCallInfo.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJConstants.$(O) AJConstants.$(H): AJConstants.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
+$(OUTDIR)AJGeneratedCode.$(O) AJGeneratedCode.$(H): AJGeneratedCode.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJInstruction.$(O) AJInstruction.$(H): AJInstruction.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJLineStream.$(O) AJLineStream.$(H): AJLineStream.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJRoutineStackManager.$(O) AJRoutineStackManager.$(H): AJRoutineStackManager.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)jv_dragonfly_asm.$(O) jv_dragonfly_asm.$(H): jv_dragonfly_asm.st $(INCLUDE_TOP)/stx/libbasic/LibraryDefinition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)AJAlignmentInstruction.$(O) AJAlignmentInstruction.$(H): AJAlignmentInstruction.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJConstants.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJCdeclCallInfo.$(O) AJCdeclCallInfo.$(H): AJCdeclCallInfo.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJCallInfo.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJData.$(O) AJData.$(H): AJData.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJConstants.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJInstructionDecoration.$(O) AJInstructionDecoration.$(H): AJInstructionDecoration.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJJumpInstruction.$(O) AJJumpInstruction.$(H): AJJumpInstruction.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJJumpLabel.$(O) AJJumpLabel.$(H): AJJumpLabel.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJOperand.$(O) AJOperand.$(H): AJOperand.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJConstants.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJReleaseTemps.$(O) AJReleaseTemps.$(H): AJReleaseTemps.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJReserveTemp.$(O) AJReserveTemp.$(H): AJReserveTemp.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJRoutineEpilogue.$(O) AJRoutineEpilogue.$(H): AJRoutineEpilogue.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJRoutinePrologue.$(O) AJRoutinePrologue.$(H): AJRoutinePrologue.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJStackInstruction.$(O) AJStackInstruction.$(H): AJStackInstruction.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJStdCallCallInfo.$(O) AJStdCallCallInfo.$(H): AJStdCallCallInfo.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJCallInfo.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86Instruction.$(O) AJx86Instruction.$(H): AJx86Instruction.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86Registers.$(O) AJx86Registers.$(H): AJx86Registers.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJConstants.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
+$(OUTDIR)AJBaseReg.$(O) AJBaseReg.$(H): AJBaseReg.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJOperand.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJCallArgument.$(O) AJCallArgument.$(H): AJCallArgument.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJStackInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJCallCleanup.$(O) AJCallCleanup.$(H): AJCallCleanup.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJStackInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJImmediate.$(O) AJImmediate.$(H): AJImmediate.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJOperand.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJMem.$(O) AJMem.$(H): AJMem.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJOperand.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64Instruction.$(O) AJx64Instruction.$(H): AJx64Instruction.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJx86Instruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86Assembler.$(O) AJx86Assembler.$(H): AJx86Assembler.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJAssembler.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJConstants.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJx86Registers.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86InstructionDescription.$(O) AJx86InstructionDescription.$(H): AJx86InstructionDescription.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJConstants.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJx86Registers.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86JumpInstruction.$(O) AJx86JumpInstruction.$(H): AJx86JumpInstruction.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJJumpInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJMMRegister.$(O) AJMMRegister.$(H): AJMMRegister.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJBaseReg.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJOperand.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJRegister.$(O) AJRegister.$(H): AJRegister.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJBaseReg.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJOperand.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64Assembler.$(O) AJx64Assembler.$(H): AJx64Assembler.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJAssembler.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJx86Assembler.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64InstructionDescription.$(O) AJx64InstructionDescription.$(H): AJx64InstructionDescription.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJx86InstructionDescription.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64JumpInstruction.$(O) AJx64JumpInstruction.$(H): AJx64JumpInstruction.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJInstruction.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJJumpInstruction.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJx86JumpInstruction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx87Register.$(O) AJx87Register.$(H): AJx87Register.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJBaseReg.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJOperand.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJxMMRegister.$(O) AJxMMRegister.$(H): AJxMMRegister.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJBaseReg.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJOperand.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86GPRegister.$(O) AJx86GPRegister.$(H): AJx86GPRegister.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJBaseReg.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJOperand.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJRegister.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJx86Registers.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64RipRegister.$(O) AJx64RipRegister.$(H): AJx64RipRegister.st $(INCLUDE_TOP)/jv/dragonfly/asm/AJBaseReg.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJOperand.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJRegister.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJx86GPRegister.$(H) $(INCLUDE_TOP)/jv/dragonfly/asm/AJx86Registers.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)/stx/libbasic/ArithmeticValue.$(H) $(INCLUDE_TOP)/stx/libbasic/Integer.$(H) $(INCLUDE_TOP)/stx/libbasic/Magnitude.$(H) $(INCLUDE_TOP)/stx/libbasic/Number.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/PeekableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/PositionableStream.$(H) $(INCLUDE_TOP)/stx/libbasic/Stream.$(H) $(INCLUDE_TOP)/stx/libbasic/WriteStream.$(H) $(STCHDR)
+
+# ENDMAKEDEPEND --- do not remove this line
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/Make.spec	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,144 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: jv_dragonfly_asm.
+#
+# Warning: once you modify this file, do not rerun
+# stmkmp or projectDefinition-build again - otherwise, your changes are lost.
+#
+# This file contains specifications which are common to all platforms.
+#
+
+# Do NOT CHANGE THESE DEFINITIONS
+# (otherwise, ST/X will have a hard time to find out the packages location from its packageID,
+#  to find the source code of a class and to find the library for a package)
+MODULE=jv
+MODULE_DIR=dragonfly/asm
+PACKAGE=$(MODULE):$(MODULE_DIR)
+
+
+# Argument(s) to the stc compiler (stc --usage).
+#  -headerDir=. : create header files locally
+#                (if removed, they will be created as common
+#  -Pxxx       : defines the package
+#  -Zxxx       : a prefix for variables within the classLib
+#  -Dxxx       : defines passed to to CC for inline C-code
+#  -Ixxx       : include path passed to CC for inline C-code
+#  +optspace   : optimized for space
+#  +optspace2  : optimized more for space
+#  +optspace3  : optimized even more for space
+#  +optinline  : generate inline code for some ST constructs
+#  +inlineNew  : additionally inline new
+#  +inlineMath : additionally inline some floatPnt math stuff
+#
+# ********** OPTIONAL: MODIFY the next line(s) ***
+# STCLOCALOPTIMIZATIONS=+optinline +inlineNew
+# STCLOCALOPTIMIZATIONS=+optspace3
+STCLOCALOPTIMIZATIONS=+optspace3
+
+
+# Argument(s) to the stc compiler (stc --usage).
+#  -warn            : no warnings
+#  -warnNonStandard : no warnings about ST/X extensions
+#  -warnEOLComments : no warnings about EOL comment extension
+#  -warnPrivacy     : no warnings about privateClass extension
+#  -warnUnused      : no warnings about unused variables
+#
+# ********** OPTIONAL: MODIFY the next line(s) ***
+# STCWARNINGS=-warn
+# STCWARNINGS=-warnNonStandard
+# STCWARNINGS=-warnEOLComments
+STCWARNINGS=-warnNonStandard
+
+COMMON_CLASSES= \
+	AJAssembler \
+	AJCallInfo \
+	AJConstants \
+	AJGeneratedCode \
+	AJInstruction \
+	AJLineStream \
+	AJRoutineStackManager \
+	jv_dragonfly_asm \
+	AJAlignmentInstruction \
+	AJCdeclCallInfo \
+	AJData \
+	AJInstructionDecoration \
+	AJJumpInstruction \
+	AJJumpLabel \
+	AJOperand \
+	AJReleaseTemps \
+	AJReserveTemp \
+	AJRoutineEpilogue \
+	AJRoutinePrologue \
+	AJStackInstruction \
+	AJStdCallCallInfo \
+	AJx86Instruction \
+	AJx86Registers \
+	AJBaseReg \
+	AJCallArgument \
+	AJCallCleanup \
+	AJImmediate \
+	AJMem \
+	AJx64Instruction \
+	AJx86Assembler \
+	AJx86InstructionDescription \
+	AJx86JumpInstruction \
+	AJMMRegister \
+	AJRegister \
+	AJx64Assembler \
+	AJx64InstructionDescription \
+	AJx64JumpInstruction \
+	AJx87Register \
+	AJxMMRegister \
+	AJx86GPRegister \
+	AJx64RipRegister \
+
+
+
+
+COMMON_OBJS= \
+    $(OUTDIR_SLASH)AJAssembler.$(O) \
+    $(OUTDIR_SLASH)AJCallInfo.$(O) \
+    $(OUTDIR_SLASH)AJConstants.$(O) \
+    $(OUTDIR_SLASH)AJGeneratedCode.$(O) \
+    $(OUTDIR_SLASH)AJInstruction.$(O) \
+    $(OUTDIR_SLASH)AJLineStream.$(O) \
+    $(OUTDIR_SLASH)AJRoutineStackManager.$(O) \
+    $(OUTDIR_SLASH)jv_dragonfly_asm.$(O) \
+    $(OUTDIR_SLASH)AJAlignmentInstruction.$(O) \
+    $(OUTDIR_SLASH)AJCdeclCallInfo.$(O) \
+    $(OUTDIR_SLASH)AJData.$(O) \
+    $(OUTDIR_SLASH)AJInstructionDecoration.$(O) \
+    $(OUTDIR_SLASH)AJJumpInstruction.$(O) \
+    $(OUTDIR_SLASH)AJJumpLabel.$(O) \
+    $(OUTDIR_SLASH)AJOperand.$(O) \
+    $(OUTDIR_SLASH)AJReleaseTemps.$(O) \
+    $(OUTDIR_SLASH)AJReserveTemp.$(O) \
+    $(OUTDIR_SLASH)AJRoutineEpilogue.$(O) \
+    $(OUTDIR_SLASH)AJRoutinePrologue.$(O) \
+    $(OUTDIR_SLASH)AJStackInstruction.$(O) \
+    $(OUTDIR_SLASH)AJStdCallCallInfo.$(O) \
+    $(OUTDIR_SLASH)AJx86Instruction.$(O) \
+    $(OUTDIR_SLASH)AJx86Registers.$(O) \
+    $(OUTDIR_SLASH)AJBaseReg.$(O) \
+    $(OUTDIR_SLASH)AJCallArgument.$(O) \
+    $(OUTDIR_SLASH)AJCallCleanup.$(O) \
+    $(OUTDIR_SLASH)AJImmediate.$(O) \
+    $(OUTDIR_SLASH)AJMem.$(O) \
+    $(OUTDIR_SLASH)AJx64Instruction.$(O) \
+    $(OUTDIR_SLASH)AJx86Assembler.$(O) \
+    $(OUTDIR_SLASH)AJx86InstructionDescription.$(O) \
+    $(OUTDIR_SLASH)AJx86JumpInstruction.$(O) \
+    $(OUTDIR_SLASH)AJMMRegister.$(O) \
+    $(OUTDIR_SLASH)AJRegister.$(O) \
+    $(OUTDIR_SLASH)AJx64Assembler.$(O) \
+    $(OUTDIR_SLASH)AJx64InstructionDescription.$(O) \
+    $(OUTDIR_SLASH)AJx64JumpInstruction.$(O) \
+    $(OUTDIR_SLASH)AJx87Register.$(O) \
+    $(OUTDIR_SLASH)AJxMMRegister.$(O) \
+    $(OUTDIR_SLASH)AJx86GPRegister.$(O) \
+    $(OUTDIR_SLASH)AJx64RipRegister.$(O) \
+    $(OUTDIR_SLASH)extensions.$(O) \
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/Makefile.init	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,27 @@
+#
+# DO NOT EDIT
+#
+# make uses this file (Makefile) only, if there is no
+# file named "makefile" (lower-case m) in the same directory.
+# My only task is to generate the real makefile and call make again.
+# Thereafter, I am no longer used and needed.
+#
+# MACOSX caveat:
+#   as filenames are not case sensitive (in a default setup),
+#   we cannot use the above trick. Therefore, this file is now named
+#   "Makefile.init", and you have to execute "make -f Makefile.init" to
+#   get the initial makefile.  This is now also done by the toplevel CONFIG
+#   script.
+
+.PHONY: run
+
+run: makefile
+	$(MAKE) -f makefile
+
+#only needed for the definition of $(TOP)
+include Make.proto
+
+makefile: mf
+
+mf:
+	$(TOP)/rules/stmkmf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/abbrev.stc	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,48 @@
+# automagically generated by the project definition
+# this file is needed for stc to be able to compile modules independently.
+# it provides information about a classes filename, category and especially namespace.
+AJAssembler AJAssembler jv:dragonfly/asm 'AsmJit-Core' 0
+AJCallInfo AJCallInfo jv:dragonfly/asm 'AsmJit-StackManagement' 0
+AJConstants AJConstants jv:dragonfly/asm 'AsmJit-Core' 0
+AJGeneratedCode AJGeneratedCode jv:dragonfly/asm 'AsmJit-Core' 0
+AJInstruction AJInstruction jv:dragonfly/asm 'AsmJit-Instructions' 0
+AJLineStream AJLineStream jv:dragonfly/asm 'AsmJit-Extension' 0
+AJRoutineStackManager AJRoutineStackManager jv:dragonfly/asm 'AsmJit-StackManagement' 0
+jv_dragonfly_asm jv_dragonfly_asm jv:dragonfly/asm '* Projects & Packages *' 3
+AJAlignmentInstruction AJAlignmentInstruction jv:dragonfly/asm 'AsmJit-Instructions' 0
+AJCdeclCallInfo AJCdeclCallInfo jv:dragonfly/asm 'AsmJit-StackManagement' 0
+AJData AJData jv:dragonfly/asm 'AsmJit-Instructions' 0
+AJInstructionDecoration AJInstructionDecoration jv:dragonfly/asm 'AsmJit-Instructions' 0
+AJJumpInstruction AJJumpInstruction jv:dragonfly/asm 'AsmJit-Instructions' 0
+AJJumpLabel AJJumpLabel jv:dragonfly/asm 'AsmJit-Instructions' 0
+AJOperand AJOperand jv:dragonfly/asm 'AsmJit-Operands' 0
+AJReleaseTemps AJReleaseTemps jv:dragonfly/asm 'AsmJit-StackManagement' 0
+AJReserveTemp AJReserveTemp jv:dragonfly/asm 'AsmJit-StackManagement' 0
+AJRoutineEpilogue AJRoutineEpilogue jv:dragonfly/asm 'AsmJit-Instructions' 0
+AJRoutinePrologue AJRoutinePrologue jv:dragonfly/asm 'AsmJit-Instructions' 0
+AJStackInstruction AJStackInstruction jv:dragonfly/asm 'AsmJit-StackManagement' 0
+AJStdCallCallInfo AJStdCallCallInfo jv:dragonfly/asm 'AsmJit-StackManagement' 0
+AJx86Instruction AJx86Instruction jv:dragonfly/asm 'AsmJit-x86-Instructions' 0
+AJx86Registers AJx86Registers jv:dragonfly/asm 'AsmJit-x86' 0
+AJBaseReg AJBaseReg jv:dragonfly/asm 'AsmJit-Operands' 0
+AJCallArgument AJCallArgument jv:dragonfly/asm 'AsmJit-StackManagement' 0
+AJCallCleanup AJCallCleanup jv:dragonfly/asm 'AsmJit-StackManagement' 0
+AJImmediate AJImmediate jv:dragonfly/asm 'AsmJit-Operands' 0
+AJMem AJMem jv:dragonfly/asm 'AsmJit-Operands' 0
+AJStackAlignmentTests AJStackAlignmentTests jv:dragonfly/asm 'AsmJit-Tests' 1
+AJx64Instruction AJx64Instruction jv:dragonfly/asm 'AsmJit-x86-Instructions' 0
+AJx86Assembler AJx86Assembler jv:dragonfly/asm 'AsmJit-x86' 0
+AJx86AssemblerTests AJx86AssemblerTests jv:dragonfly/asm 'AsmJit-Tests' 1
+AJx86InstructionDescription AJx86InstructionDescription jv:dragonfly/asm 'AsmJit-x86-Instructions' 2
+AJx86JumpInstruction AJx86JumpInstruction jv:dragonfly/asm 'AsmJit-x86-Instructions' 0
+AJx86RegisterTests AJx86RegisterTests jv:dragonfly/asm 'AsmJit-Tests' 1
+AJMMRegister AJMMRegister jv:dragonfly/asm 'AsmJit-x86-Operands' 0
+AJRegister AJRegister jv:dragonfly/asm 'AsmJit-Operands' 0
+AJx64Assembler AJx64Assembler jv:dragonfly/asm 'AsmJit-x86' 0
+AJx64AssemblerTests AJx64AssemblerTests jv:dragonfly/asm 'AsmJit-Tests' 1
+AJx64InstructionDescription AJx64InstructionDescription jv:dragonfly/asm 'AsmJit-x86-Instructions' 2
+AJx64JumpInstruction AJx64JumpInstruction jv:dragonfly/asm 'AsmJit-x86-Instructions' 0
+AJx87Register AJx87Register jv:dragonfly/asm 'AsmJit-x86-Operands' 0
+AJxMMRegister AJxMMRegister jv:dragonfly/asm 'AsmJit-x86-Operands' 0
+AJx86GPRegister AJx86GPRegister jv:dragonfly/asm 'AsmJit-x86-Operands' 0
+AJx64RipRegister AJx64RipRegister jv:dragonfly/asm 'AsmJit-x86-Operands' 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/asm.rc	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,37 @@
+//
+// DO NOT EDIT
+// automagically generated from the projectDefinition: jv_dragonfly_asm.
+//
+VS_VERSION_INFO VERSIONINFO
+  FILEVERSION     6,2,32767,32767
+  PRODUCTVERSION  6,2,5,0
+#if (__BORLANDC__)
+  FILEFLAGSMASK   VS_FF_DEBUG | VS_FF_PRERELEASE
+  FILEFLAGS       VS_FF_PRERELEASE | VS_FF_SPECIALBUILD
+  FILEOS          VOS_NT_WINDOWS32
+  FILETYPE        VFT_DLL
+  FILESUBTYPE     VS_USER_DEFINED
+#endif
+
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    BEGIN
+      VALUE "CompanyName", "My Company\0"
+      VALUE "FileDescription", "Class Library (LIB)\0"
+      VALUE "FileVersion", "6.2.32767.32767\0"
+      VALUE "InternalName", "jv:dragonfly/asm\0"
+      VALUE "LegalCopyright", "My CopyRight or CopyLeft\0"
+      VALUE "ProductName", "LibraryName\0"
+      VALUE "ProductVersion", "6.2.5.0\0"
+      VALUE "ProductDate", "Tue, 15 Dec 2015 23:15:54 GMT\0"
+    END
+
+  END
+
+  BLOCK "VarFileInfo"
+  BEGIN                               //  Language   |    Translation
+    VALUE "Translation", 0x409, 0x4E4 // U.S. English, Windows Multilingual
+  END
+END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/bc.mak	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,123 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: jv_dragonfly_asm.
+#
+# Warning: once you modify this file, do not rerun
+# stmkmp or projectDefinition-build again - otherwise, your changes are lost.
+#
+# Notice, that the name bc.mak is historical (from times, when only borland c was supported).
+# This file contains make rules for the win32 platform using either borland-bcc or visual-c.
+# It shares common definitions with the unix-make in Make.spec.
+# The bc.mak supports the following targets:
+#    bmake         - compile all st-files to a classLib (dll)
+#    bmake clean   - clean all temp files
+#    bmake clobber - clean all
+#
+# Historic Note:
+#  this used to contain only rules to make with borland
+#    (called via bmake, by "make.exe -f bc.mak")
+#  this has changed; it is now also possible to build using microsoft visual c
+#    (called via vcmake, by "make.exe -f bc.mak -DUSEVC")
+#
+TOP=..\..\..\stx
+INCLUDE_TOP=$(TOP)\..
+
+
+
+!INCLUDE $(TOP)\rules\stdHeader_bc
+
+!INCLUDE Make.spec
+
+LIBNAME=libjv_dragonfly_asm
+MODULE_PATH=dragonfly\asm
+RESFILES=asm.$(RES)
+
+
+
+LOCALINCLUDES= -I$(INCLUDE_TOP)\stx\goodies\sunit -I$(INCLUDE_TOP)\stx\libbasic
+LOCALDEFINES=
+
+STCLOCALOPT=-package=$(PACKAGE) -I. $(LOCALINCLUDES) -headerDir=. $(STCLOCALOPTIMIZATIONS) $(STCWARNINGS) $(LOCALDEFINES)  -varPrefix=$(LIBNAME)
+LOCALLIBS=
+
+OBJS= $(COMMON_OBJS) $(WIN32_OBJS)
+
+ALL::  classLibRule
+
+classLibRule: $(OUTDIR) $(OUTDIR)$(LIBNAME).dll
+
+!INCLUDE $(TOP)\rules\stdRules_bc
+
+# build all mandatory prerequisite packages (containing superclasses) for this package
+prereq:
+	pushd ..\..\..\stx\libbasic & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+
+
+
+
+
+
+
+test: $(TOP)\goodies\builder\reports\NUL
+	pushd $(TOP)\goodies\builder\reports & $(MAKE_BAT)
+	$(TOP)\goodies\builder\reports\report-runner.bat -D . -r Builder::TestReport -p $(PACKAGE)
+        
+clean::
+	del *.$(CSUFFIX)
+
+
+# BEGINMAKEDEPEND --- do not remove this line; make depend needs it
+$(OUTDIR)AJAssembler.$(O) AJAssembler.$(H): AJAssembler.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJCallInfo.$(O) AJCallInfo.$(H): AJCallInfo.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJConstants.$(O) AJConstants.$(H): AJConstants.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
+$(OUTDIR)AJGeneratedCode.$(O) AJGeneratedCode.$(H): AJGeneratedCode.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJInstruction.$(O) AJInstruction.$(H): AJInstruction.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJLineStream.$(O) AJLineStream.$(H): AJLineStream.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJRoutineStackManager.$(O) AJRoutineStackManager.$(H): AJRoutineStackManager.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)jv_dragonfly_asm.$(O) jv_dragonfly_asm.$(H): jv_dragonfly_asm.st $(INCLUDE_TOP)\stx\libbasic\LibraryDefinition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)AJAlignmentInstruction.$(O) AJAlignmentInstruction.$(H): AJAlignmentInstruction.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJConstants.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJCdeclCallInfo.$(O) AJCdeclCallInfo.$(H): AJCdeclCallInfo.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJCallInfo.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJData.$(O) AJData.$(H): AJData.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJConstants.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJInstructionDecoration.$(O) AJInstructionDecoration.$(H): AJInstructionDecoration.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJJumpInstruction.$(O) AJJumpInstruction.$(H): AJJumpInstruction.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJJumpLabel.$(O) AJJumpLabel.$(H): AJJumpLabel.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJOperand.$(O) AJOperand.$(H): AJOperand.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJConstants.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJReleaseTemps.$(O) AJReleaseTemps.$(H): AJReleaseTemps.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJReserveTemp.$(O) AJReserveTemp.$(H): AJReserveTemp.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJRoutineEpilogue.$(O) AJRoutineEpilogue.$(H): AJRoutineEpilogue.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJRoutinePrologue.$(O) AJRoutinePrologue.$(H): AJRoutinePrologue.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJStackInstruction.$(O) AJStackInstruction.$(H): AJStackInstruction.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJStdCallCallInfo.$(O) AJStdCallCallInfo.$(H): AJStdCallCallInfo.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJCallInfo.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86Instruction.$(O) AJx86Instruction.$(H): AJx86Instruction.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86Registers.$(O) AJx86Registers.$(H): AJx86Registers.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJConstants.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
+$(OUTDIR)AJBaseReg.$(O) AJBaseReg.$(H): AJBaseReg.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJOperand.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJCallArgument.$(O) AJCallArgument.$(H): AJCallArgument.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJStackInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJCallCleanup.$(O) AJCallCleanup.$(H): AJCallCleanup.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJStackInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJImmediate.$(O) AJImmediate.$(H): AJImmediate.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJOperand.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJMem.$(O) AJMem.$(H): AJMem.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJOperand.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64Instruction.$(O) AJx64Instruction.$(H): AJx64Instruction.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJx86Instruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86Assembler.$(O) AJx86Assembler.$(H): AJx86Assembler.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJAssembler.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJConstants.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJx86Registers.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86InstructionDescription.$(O) AJx86InstructionDescription.$(H): AJx86InstructionDescription.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJConstants.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJx86Registers.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86JumpInstruction.$(O) AJx86JumpInstruction.$(H): AJx86JumpInstruction.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJJumpInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJMMRegister.$(O) AJMMRegister.$(H): AJMMRegister.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJBaseReg.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJOperand.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJRegister.$(O) AJRegister.$(H): AJRegister.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJBaseReg.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJOperand.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64Assembler.$(O) AJx64Assembler.$(H): AJx64Assembler.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJAssembler.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJx86Assembler.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64InstructionDescription.$(O) AJx64InstructionDescription.$(H): AJx64InstructionDescription.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJx86InstructionDescription.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64JumpInstruction.$(O) AJx64JumpInstruction.$(H): AJx64JumpInstruction.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJInstruction.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJJumpInstruction.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJx86JumpInstruction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx87Register.$(O) AJx87Register.$(H): AJx87Register.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJBaseReg.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJOperand.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJxMMRegister.$(O) AJxMMRegister.$(H): AJxMMRegister.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJBaseReg.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJOperand.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx86GPRegister.$(O) AJx86GPRegister.$(H): AJx86GPRegister.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJBaseReg.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJOperand.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJRegister.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJx86Registers.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)AJx64RipRegister.$(O) AJx64RipRegister.$(H): AJx64RipRegister.st $(INCLUDE_TOP)\jv\dragonfly\asm\AJBaseReg.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJOperand.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJRegister.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJx86GPRegister.$(H) $(INCLUDE_TOP)\jv\dragonfly\asm\AJx86Registers.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)\stx\libbasic\ArithmeticValue.$(H) $(INCLUDE_TOP)\stx\libbasic\Integer.$(H) $(INCLUDE_TOP)\stx\libbasic\Magnitude.$(H) $(INCLUDE_TOP)\stx\libbasic\Number.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\PeekableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\PositionableStream.$(H) $(INCLUDE_TOP)\stx\libbasic\Stream.$(H) $(INCLUDE_TOP)\stx\libbasic\WriteStream.$(H) $(STCHDR)
+
+# ENDMAKEDEPEND --- do not remove this line
+
+# **Must be at end**
+
+# Enforce recompilation of package definition class if Mercurial working
+# copy state changes. Together with --guessVersion it ensures that package
+# definition class always contains correct binary revision string.
+!IFDEF HGROOT
+$(OUTDIR)jv_dragonfly_asm.$(O): $(HGROOT)\.hg\dirstate
+!ENDIF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/bmake.bat	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,13 @@
+@REM -------
+@REM make using Borland bcc32
+@REM type bmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+@SET DEFINES=
+@REM Kludge got Mercurial, cannot be implemented in Borland make
+@FOR /F "tokens=*" %%i in ('hg root') do SET HGROOT=%%i
+@IF "%HGROOT%" NEQ "" SET DEFINES=%DEFINES% "-DHGROOT=%HGROOT%"
+
+make.exe -N -f bc.mak  %DEFINES% %*
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/extensions.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,150 @@
+"{ Package: 'jv:dragonfly/asm' }"!
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asAJOperand
+
+    "Convert receiver into operand: a signed immediate"
+    ^ AJImmediate new ivalue: self
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asByte
+    ^ self asTwosComplement: 16rFF
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asDoubleWord
+    ^ self asTwosComplement: 16rFFFFFFFF
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asImm
+
+    "Convert integer value into a signed immediate operand"
+    ^ AJImmediate new ivalue: self
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asImm16
+
+    "Convert integer value into a signed immediate word operand "
+    ^ AJImmediate new ivalue: self; size: 2
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asImm32
+
+    "Convert integer value into a signed immediate operand"
+    ^ AJImmediate new ivalue: self; size: 4
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asImm8
+
+    "Convert integer value into a signed immediate operand"
+    ^ AJImmediate new ivalue: self; size: 1
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asQuadWord
+    ^ self asTwosComplement: 16rFFFFFFFFFFFFFFFF
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asTwosComplement: mask
+    "return the two's completemented cropped version.
+    Example for a byte value:
+        -5 asTwosComplement: 16rFF "
+    | bound |
+    bound := (mask + 1).
+    
+    self * 2 >= bound 
+        ifTrue: [Error signal: self printString , ' too big for signed ', mask highBit printString,  'bit value'].
+         
+    (self >= 0)
+        ifTrue: [ ^ self bitAnd: mask ].
+        
+    self * 2 < bound negated 
+        ifTrue: [Error signal: self printString , ' too small for signed ', mask highBit printString, 'bit value'].
+        
+    ^ (self + mask + 1) bitAnd: mask
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asUImm
+
+    "Convert integer value into an unsigned immediate operand"
+    ^ AJImmediate new uvalue: self
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asUImm16
+
+    "Convert integer value into an unsigned immediate operand"
+    ^ AJImmediate new uvalue: self; size: 2
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asUImm32
+
+    "Convert integer value into an unsigned immediate operand"
+    ^ AJImmediate new uvalue: self; size: 4
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asUImm8
+
+    "Convert integer value into an unsigned immediate operand"
+    ^ AJImmediate new uvalue: self; size: 1
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+asWord
+    ^ self asTwosComplement: 16rFFFF
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+bin
+    "Print the receiver as hex, prefixed with 2r."
+    ^self storeStringBase: 2
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+isByte
+    ^ self >= 0 and: [ self <= 255 ]
+! !
+
+!Integer methodsFor:'*AsmJit-Extension'!
+
+printAsOperandOn: aStream
+    aStream print: self.
+! !
+
+!WriteStream methodsFor:'*AsmJit-Extension'!
+
+asLineStream
+    ^ AJLineStream on: self
+! !
+
+!jv_dragonfly_asm class methodsFor:'documentation'!
+
+extensionsVersion_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/jv_dragonfly_asm.st	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,181 @@
+"{ Package: 'jv:dragonfly/asm' }"
+
+"{ NameSpace: Smalltalk }"
+
+LibraryDefinition subclass:#jv_dragonfly_asm
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'* Projects & Packages *'
+!
+
+
+!jv_dragonfly_asm class methodsFor:'description'!
+
+excludedFromPreRequisites
+    "list packages which are to be explicitely excluded from the automatic constructed
+     prerequisites list. If empty, everything that is found along the inheritance of any of
+     my classes is considered to be a prerequisite package."
+
+    ^ #(
+    )
+!
+
+mandatoryPreRequisites
+    "list packages which are mandatory as a prerequisite.
+     This are packages containing superclasses of my classes and classes which
+     are extended by myself.
+     They are mandatory, because we need these packages as a prerequisite for loading and compiling.
+     This method is generated automatically,
+     by searching along the inheritance chain of all of my classes."
+
+    ^ #(
+        #'stx:libbasic'    "ArithmeticValue - extended"
+    )
+!
+
+referencedPreRequisites
+    "list packages which are a prerequisite, because they contain
+     classes which are referenced by my classes.
+     We do not need these packages as a prerequisite for compiling or loading,
+     however, a class from it may be referenced during execution and having it
+     unloaded then may lead to a runtime doesNotUnderstand error, unless the caller
+     includes explicit checks for the package being present.
+     This method is generated automatically,
+     by searching all classes (and their packages) which are referenced by my classes."
+
+    ^ #(
+        #'stx:goodies/sunit'    "TestAsserter - superclass of AJStackAlignmentTests"
+    )
+!
+
+subProjects
+    "list packages which are known as subprojects.
+     The generated makefile will enter those and make there as well.
+     However: they are not forced to be loaded when a package is loaded;
+     for those, redefine requiredPrerequisites."
+
+    ^ #(
+    )
+! !
+
+!jv_dragonfly_asm class methodsFor:'description - contents'!
+
+classNamesAndAttributes
+    "lists the classes which are to be included in the project.
+     Each entry in the list may be: a single class-name (symbol),
+     or an array-literal consisting of class name and attributes.
+     Attributes are: #autoload or #<os> where os is one of win32, unix,..."
+
+    ^ #(
+        "<className> or (<className> attributes...) in load order"
+        AJAssembler
+        AJCallInfo
+        AJConstants
+        AJGeneratedCode
+        AJInstruction
+        AJLineStream
+        AJRoutineStackManager
+        #'jv_dragonfly_asm'
+        AJAlignmentInstruction
+        AJCdeclCallInfo
+        AJData
+        AJInstructionDecoration
+        AJJumpInstruction
+        AJJumpLabel
+        AJOperand
+        AJReleaseTemps
+        AJReserveTemp
+        AJRoutineEpilogue
+        AJRoutinePrologue
+        AJStackInstruction
+        AJStdCallCallInfo
+        AJx86Instruction
+        AJx86Registers
+        AJBaseReg
+        AJCallArgument
+        AJCallCleanup
+        AJImmediate
+        AJMem
+        (AJStackAlignmentTests autoload)
+        AJx64Instruction
+        AJx86Assembler
+        (AJx86AssemblerTests autoload)
+        AJx86InstructionDescription
+        AJx86JumpInstruction
+        (AJx86RegisterTests autoload)
+        AJMMRegister
+        AJRegister
+        AJx64Assembler
+        (AJx64AssemblerTests autoload)
+        AJx64InstructionDescription
+        AJx64JumpInstruction
+        AJx87Register
+        AJxMMRegister
+        AJx86GPRegister
+        AJx64RipRegister
+    )
+!
+
+extensionMethodNames
+    "list class/selector pairs of extensions.
+     A correponding method with real names must be present in my concrete subclasses"
+
+    ^ #(
+        Integer asAJOperand
+        Integer asByte
+        Integer asDoubleWord
+        Integer asImm
+        Integer asImm16
+        Integer asImm32
+        Integer asImm8
+        Integer asQuadWord
+        Integer asTwosComplement:
+        Integer asUImm
+        Integer asUImm16
+        Integer asUImm32
+        Integer asUImm8
+        Integer asWord
+        Integer bin
+        Integer isByte
+        Integer printAsOperandOn:
+        WriteStream asLineStream
+    )
+! !
+
+!jv_dragonfly_asm class methodsFor:'description - project information'!
+
+companyName
+    "Returns a company string which will appear in <lib>.rc.
+     Under win32, this is placed into the dlls file-info"
+
+    ^ 'My Company'
+!
+
+description
+    "Returns a description string which will appear in nt.def / bc.def"
+
+    ^ 'Class Library'
+!
+
+legalCopyright
+    "Returns a copyright string which will appear in <lib>.rc.
+     Under win32, this is placed into the dlls file-info"
+
+    ^ 'My CopyRight or CopyLeft'
+!
+
+productName
+    "Returns a product name which will appear in <lib>.rc.
+     Under win32, this is placed into the dlls file-info.
+     This method is usually redefined in a concrete application definition"
+
+    ^ 'LibraryName'
+! !
+
+!jv_dragonfly_asm class methodsFor:'documentation'!
+
+version_HG
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/libInit.cc	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,74 @@
+/*
+ * $Header$
+ *
+ * DO NOT EDIT
+ * automagically generated from the projectDefinition: jv_dragonfly_asm.
+ */
+#define __INDIRECTVMINITCALLS__
+#include <stc.h>
+
+#ifdef WIN32
+# pragma codeseg INITCODE "INITCODE"
+#endif
+
+#if defined(INIT_TEXT_SECTION) || defined(DLL_EXPORT)
+DLL_EXPORT void _libjv_dragonfly_asm_Init() INIT_TEXT_SECTION;
+DLL_EXPORT void _libjv_dragonfly_asm_InitDefinition() INIT_TEXT_SECTION;
+#endif
+
+void _libjv_dragonfly_asm_InitDefinition(pass, __pRT__, snd)
+OBJ snd; struct __vmData__ *__pRT__; {
+__BEGIN_PACKAGE2__("libjv_dragonfly_asm__DFN", _libjv_dragonfly_asm_InitDefinition, "jv:dragonfly/asm");
+_jv_137dragonfly_137asm_Init(pass,__pRT__,snd);
+
+__END_PACKAGE__();
+}
+
+void _libjv_dragonfly_asm_Init(pass, __pRT__, snd)
+OBJ snd; struct __vmData__ *__pRT__; {
+__BEGIN_PACKAGE2__("libjv_dragonfly_asm", _libjv_dragonfly_asm_Init, "jv:dragonfly/asm");
+_AJAssembler_Init(pass,__pRT__,snd);
+_AJCallInfo_Init(pass,__pRT__,snd);
+_AJConstants_Init(pass,__pRT__,snd);
+_AJGeneratedCode_Init(pass,__pRT__,snd);
+_AJInstruction_Init(pass,__pRT__,snd);
+_AJLineStream_Init(pass,__pRT__,snd);
+_AJRoutineStackManager_Init(pass,__pRT__,snd);
+_jv_137dragonfly_137asm_Init(pass,__pRT__,snd);
+_AJAlignmentInstruction_Init(pass,__pRT__,snd);
+_AJCdeclCallInfo_Init(pass,__pRT__,snd);
+_AJData_Init(pass,__pRT__,snd);
+_AJInstructionDecoration_Init(pass,__pRT__,snd);
+_AJJumpInstruction_Init(pass,__pRT__,snd);
+_AJJumpLabel_Init(pass,__pRT__,snd);
+_AJOperand_Init(pass,__pRT__,snd);
+_AJReleaseTemps_Init(pass,__pRT__,snd);
+_AJReserveTemp_Init(pass,__pRT__,snd);
+_AJRoutineEpilogue_Init(pass,__pRT__,snd);
+_AJRoutinePrologue_Init(pass,__pRT__,snd);
+_AJStackInstruction_Init(pass,__pRT__,snd);
+_AJStdCallCallInfo_Init(pass,__pRT__,snd);
+_AJx86Instruction_Init(pass,__pRT__,snd);
+_AJx86Registers_Init(pass,__pRT__,snd);
+_AJBaseReg_Init(pass,__pRT__,snd);
+_AJCallArgument_Init(pass,__pRT__,snd);
+_AJCallCleanup_Init(pass,__pRT__,snd);
+_AJImmediate_Init(pass,__pRT__,snd);
+_AJMem_Init(pass,__pRT__,snd);
+_AJx64Instruction_Init(pass,__pRT__,snd);
+_AJx86Assembler_Init(pass,__pRT__,snd);
+_AJx86InstructionDescription_Init(pass,__pRT__,snd);
+_AJx86JumpInstruction_Init(pass,__pRT__,snd);
+_AJMMRegister_Init(pass,__pRT__,snd);
+_AJRegister_Init(pass,__pRT__,snd);
+_AJx64Assembler_Init(pass,__pRT__,snd);
+_AJx64InstructionDescription_Init(pass,__pRT__,snd);
+_AJx64JumpInstruction_Init(pass,__pRT__,snd);
+_AJx87Register_Init(pass,__pRT__,snd);
+_AJxMMRegister_Init(pass,__pRT__,snd);
+_AJx86GPRegister_Init(pass,__pRT__,snd);
+_AJx64RipRegister_Init(pass,__pRT__,snd);
+
+_jv_137dragonfly_137asm_extensions_Init(pass,__pRT__,snd);
+__END_PACKAGE__();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/mingwmake.bat	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,16 @@
+@REM -------
+@REM make using mingw gnu compiler
+@REM type mingwmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+@SET DEFINES=
+@REM Kludge got Mercurial, cannot be implemented in Borland make
+@FOR /F "tokens=*" %%i in ('hg root') do SET HGROOT=%%i
+@IF "%HGROOT%" NEQ "" SET DEFINES=%DEFINES% "-DHGROOT=%HGROOT%"
+
+@pushd ..\..\..\stx\rules
+@call find_mingw.bat
+@popd
+make.exe -N -f bc.mak %DEFINES% %USEMINGW_ARG% %*
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm/vcmake.bat	Tue Dec 15 23:18:02 2015 +0000
@@ -0,0 +1,21 @@
+@REM -------
+@REM make using Microsoft Visual C compiler
+@REM type vcmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+
+@if not defined VSINSTALLDIR (
+    pushd ..\..\..\stx\rules
+    call vcsetup.bat
+    popd
+)
+@SET DEFINES=
+@REM Kludge got Mercurial, cannot be implemented in Borland make
+@FOR /F "tokens=*" %%i in ('hg root') do SET HGROOT=%%i
+@IF "%HGROOT%" NEQ "" SET DEFINES=%DEFINES% "-DHGROOT=%HGROOT%"
+
+
+make.exe -N -f bc.mak -DUSEVC=1 %DEFINES% %*
+
+
+