define(__)

__(	"__( stuff)" 	 is now a comment.

x86 asmacs, humbubba@smart.net  Rick Hohensee 2000 

It's back to the future, AGAIN! Compilers are CPU-independant 
assembler pre-processors. asmacs is a CPU-specific assembler
pre-processor. This is asmacs x86. The abstractions constructed here are
in support of the fourth-generation language Ha3sm. Therefor the goal is
not to be platform-independant at the conclusion of pre-processing. The
simplicity and modularity of Ha3sm will probably have to stand in stead
for the advantages of platform-independance. Ha3sm defines the portable
layer. I guess. 

m4 allows C-style macro names, like _10 but not other punctuation marks
which is just as well since this has to go through gas also.

 Registers
 core			)

define(A,%eax)
define(B,%ebx)
define(C,%ecx)
define(D,%edx)
define(port,%edx)
define(SP,%esp)
define(counter,%ecx)
define(amount,%cl)
define(dest,%edi)
define(source,%esi)
define(stash,%dr0)
define(stash0,%dr0)
define(stash1,%dr1)
define(stash2,%dr2)

__( instuction name transliterations. Some rep macros. )

define(asciiadjustafteraddition,aaa)	__( 4004 stuff? )
define(asciiadjustbefordivision,aad)
define(asciiadjustaftermultiply,aam)
define(asciiadjustaftersubtraction,aas)

__(add,add)				__( source + dest -> dest. 
					no carry added. Immediate byte
					operands are sgn-extended if nec.)

define(AND,and)				__( I like all-caps for Booleans.
						Not sure why. )

define(within,bound)			__( BOUND r32,m32&32     10
					Check if r32 is within bounds 
					m32&32 is two adjacent indices 
					in memory)

define(setGDT,lgdt)			__(Global Descriptor Table   ) 
define(setIDT,lidt)			__(Interrupt...              )
define(setLDT,lldt)			__( local descriptor table )

define(MS1bit,bsr)			
define(LS1bit,bsf)			__( find least-significance 1-bit 
					op scanned, bitposition )

define(addwithcarry,adc)		__( source + dest + c -> dest 
					immediate bytes are sign-extended)

define(ifbit,bt)
define(biton,bts)			
define(bitoff,btr)				__( op base, bit-index
						bit -> CF ; 0 -> bit )
__(call,`call')			
define(bytecomparesegment,`rep scasb counter,')
define(dualcomparesegment,`rep scasw counter,')
define(quadcomparesegment,`rep scasd counter,')

define(copybytesegment,`rep movsb counter,' )
define(copydualsegment,`rep movsw counter,' )
define(copyquadsegment,`rep movsd counter,' )
define(copy,movl)
define(copyextend,movsx)
define(copy0extend,movzx)
define(quadextend,cdq)				__( sign of A extended to D
								2 clocks )
define(dualaexendedtod,cwd)			__( sign of ax extended to dx)	
define(decreasing,std ;)
define(decrement,dec)
define(dsfar,lds)
define(escape,iret ;)
define(esfar,les)
define(exchange,xchg)
define(bytetodualsigned,cbw)				__( 3 clocks )
define(bytetodual,cbw)					__( 3 clocks )
define(dualtoquadsigned,cbwe)				__( 3 clocks )
define(dualtoquad,cbwe)					__( 3 clocks )
define(clearcarry,clc)					__( 2 clocks )
define(DecimalAdjustafterAddition,daa)
define(DecimalAdjustafterSubtraction,das)
__(enter,`enter')			__( make a pascal stack frame )
define(flagcarry,setc)
define(flagcarryORoverflow,setbe)
define(flagnocarry,setae)
define(flagnocarryANDnonzero,seta)
define(flagnonzero,setne)
define(flanonzeroORsignequalsoverflow,setg)
define(flagnooverflow,setno)
define(flagoddparity,setpo)
define(flagoverflow,seto)
define(flagparity,setp)
define(flagpositive,setns)
define(flags,lahf)			__( FLAGS -> ah )
define(flagsign,sets)
define(flagsignaintoverflow,setl)
define(flagsignequalsoverflow,setge)
define(flagzero,sete)
define(flagzeroANDsignaintoverflow,setle)
define(flagzeroORsignaintoverflow,setng)
define(fsfar,lfs)
define(gsfar,lgs)
define(ifAND,test)
define(ifsubtract,cmp)			__( op sign-extended, other 
					assert flags as if minus. 
					2 or 5 clocks )

  					__( repeating compares,
					source - dest for count 
					operands are reversed from usual
					Intel convention.)
define(ifsubtractsegment,`rep cmps counter,')		__( op a , b )
define(ifsubtractbytesegment,`rep cmpsb counter,')		__( op )
define(ifsubtractdualsegment,`rep cmpsw counter,')
define(ifsubtractquadsegment,`rep cmpsd counter,')
define(smsw,`smsw')			__( sto mach. status wd ) 

define(increasing,cld ;)		__( 2 clocks 
					set segment op direction flag)
define(increment,inc)
define(interrupts,sti ;)
define(subtract,sub)			__( small literals are extended )

define(jump,jmp)	__( ell, to... ) 
			__( jumps on flag conditions. Incomplete. )
define(ja,`ja')				__( CF = 0  AND ZF = 0	)
define(ifnocarryjump,jae)		__( CF = 0	)
define(ifcarrryjump,jb)			__( carry = 1	) 
define(jbe,`jbe')
define(ifcx0jump,jcxz)			__( cx = 0 	)
define(ifcount0jump,jecxz)		__( ecx = 0 	)
define(if0jump,jz)			__( ZF = 1 	)
__(jg,`jg')				__( ZF = 0 AND SF = OF )
__(jge,`jge')				__(SF = OF 	)
__(jl,`jl')				__(SF <> OF	)
__(jle,`jle)				__(SF <> OF AND ZF = 1 )
__(jna,jna)				__(CF or ZF = 1 )		
__(jno,jno)				__(OF = 0 )	
__(jnp,jnp)				__(!pf )	
__(jns,jns)				__(!SF)

__(lea,lea)				__( I don't get this one at all.
						Paging stuff? )
__(leave,leave)			__( opposite of enter )
define(limit,lsl)			__( load reg with segment limit )
define(loadbytesegment,lodsb)		
define(loaddualsegment,lodsw)		
define(loadquadsegment,lodsd)		__( load A with (so urce), then
					sized-increment source. Useful
					with loop but not rep . )

__(lock,lock)			__( instruction prefix 
					looks like an SMP thing )

define(lookup,xlatb)			__(  [ebx + al] -> al )


__(loop,loop)			__( 11 clocks, 
					decrement count; loop if count = 0)
__(loopz,loopz)			__(and  ZF = 1 ) 
__(loopnz,loopnz)			__(and  ZF = 0 )

define(loadmachinestatusword,lmsw)		__( 286 thing, but works)
define(multiply,imul)
define(negate,neg)			__( 2's complement )
define(nocarry,clc ;)
__(nop,nop)
define(NOT,not)
define(nointerrupts,cli	;)		__( 3 clocks )
define(clearswitched,clts ;)		__( clear task-switched
					flag in cr0. 5 clocks. )

define(OR,or)
define(otheroperandsize, .byte 0x66 ; )		__( instruction prefix )
define(otheraddresssize, .byte 0x67 ; )		__( instruction prefix )
define(overtrap,into ;)			__( trap 4 on overflow )
define(priviledge,arpl)			__( adjust RPL field of selector )
define(pullcore,popa ;)			__( 24 clocks )
define(pullflags,popf ;)
define(pushcore,pusha ;)		__( 18 clocks. Not bad. )
define(pushflags,pushf ;)
define(readable,verr)

define(recieve,in)			__( port is edx, dest is eax)
define(recievebytes, rep insb)		__( port is edx, dest is (edi))
define(recieveduals, rep insw)		__( edi is auto-incremented )
define(recievequads, rep insd)

define(repeating,rep ;)			__( prefix, one instruction looper )
define(repeat0,repz ;)			__( prefix, one instruction looper  )
define(repeatnon0,repnz ;)		__( prefix, one instruction looper )
define(return,ret ;)
define(getrights,lar)			__( get access rights from
						descriptor)

define(GDT,sgdt)			__( get GDT to , uh )
define(IDT,sidt)
define(LDT,sldt)

__( the Load Full Pointer 
	instructions are lcs, lds, etc. )

define(savetask,str)
define(send,out)
define(sendbytesegment,`rep outsb counter,' )
define(senddualsegment,`rep outsw counter,' )
define(sendquadsegment,`rep outsd counter,' )
define(setcarry,stc ;)
define(setflags,sahf ;)			__( from ah )
define(sleep,hlt ;)			__( priviledged insn )
define(ssfar,lss)
define(bytefill,`rep stosb counter,')
define(dualfill,`rep stosw counter,')
define(quadfill,`rep stosd counter,')
define(upshift,sal)
define(downshift,sar)
define(subtract,sbb)		__( with borrow )
define(task,ltr)		__( load task reg )
define(trap,int)
define(umultiply,mul)
define(unbit,btc)		__( bit -> CF; !bit -> bit
				BTC bitoffset base  )

define(complementcarry,cmc ;)	__( 2 clocks )

define(signeddivide,idiv)	
define(unsigneddivide,div)	__( 32 bit is 38/41 clocks
				op divisor
				dividend in eax; quo in eax, mod in edx )

define(uprollcarry,rcl)
define(downrollcarry,rcr)
define(uproll,rol)
define(downroll,ror)
define(widedownshift,shrd)
define(wideupshift,shld)
define(writeable,verw)
define(XOR,xor)

__( sugar )

define(to,`,')
define(plus,`,')
define(scaled_by,`,')
define(no_base,`,')

__( gas directives transliterations )

define(_byte,.byte)
define(_dual,.word)
define(_cell,.long)
define(_quad,.long)
define(_assembling_32,.code32)
define(_assembling_16,.code16)


__( ######################################################################
# Ha3sm, # Ha3sm, # Ha3sm, # Ha3sm, 

####### Ha3sm, virtual registers

SCHEME
I leave ecx, esi and edi open for pyte operations with movs,
rep, loop and friends.
They get counted down by string rep and loop constructs,
so it's save&restore to keep the pyte stack pointer in them,
versus one copy if those things reside non-transiently elsewhere. 
)


__(  probably pointless at this level, but... ) 
__( bus size )
define(cellsize, 4)

__( VM regs )
define(RSI,%esp)		__(` # hardware return stack')
define(PSI,%ebp)		__(` # pointer stack index')
define(SI, %ebx)		__(` # pyte Stack Index ')
define(Size,%edx)		__( port also )

__( transient VM reg )

define(PTOS, %esi )

__( contents of stack indices )

		__( contents of Top Of Pointer Stack )
define(TOPS, `(,PSI,cellsize)' )

		__( contents of Previous Top Of Pointer Stack )
define(PTOPS, `-cellsize(,PSI,cellsize)' )

		__( contents of Top Of pyte Stack )
define(TOS,`(SI)')
		__( PTOS would be -Size`(SI)' if it was possible )

define(setsource,
		`copy SI to source'		
)

define(setdest,
		`copy SI to dest'
)

__( sub-primitives, i.e. in-lines the next two can be 1 increments if we
keep PSI to be indexed by the memory addressing mode. Oooo, BARGAIN! )

define(PBUMP, 
	`increment PSI ;')

define(PDROP, 
	`decrement PSI ;')

define(setPTOS,
	 `copy SI to source ;')

define(DROP, 
	`sub Size to SI ;' )

define(BUMP, 
	`add Size to SI ;' )

define(stashSize,
`copy Size to stash' 
$* 
`copy stash to Size')

		__(  set up source by hand. Note the label argument.
			This is a do-while with i in %cl. The loop
			happens at least once, once if cl is 1. )
define(labeledloop,
`copy SI to dest'
`copy Size to counter'
$1:
	`shift($*)' 
`loop' $1)

