define(__)

__( __( stuff) <--- is now a comment. __( __( Nestable, even. ) )

x86 asmacs, humbubba@smart.net  Rick Hohensee 2000 

m4 assembler macros for GNU as x86 for Ha3sm. 

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.


generic instruction name transliterations. Some rep macros. 
)
define(asciifixaddition,aaa)	__( 4004 stuff? )
define(asciifixdivision,aad)
define(asciifixmultiply,aam)
define(asciifixsubtraction,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(bytesegmentcompare,`rep ; scasb counter,')
define(dualsegmentcompare,`rep ; scasw counter,')
define(quadsegmentcompare,`rep ; scasd counter,')

define(bytesegmentcopy,`rep ; movsb counter,' )
define(dualsegmentopy, `rep ; movsw counter,' )
define(quadsegmentcopy,`rep ; movsd counter,' )
define(copy,movl)
define(copyextend,movsx)
define(copy0extend,movzx)
define(quadextend,cdq)				__( sign of A extended to D
								2 clocks )

define(extendaxtodx,cwd)

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(DecimalfixAddition,daa)
define(DecimalfixSubtraction,das)
__(enter,`enter')			__( make a pascal-style module  
						stack frame )

define(flags,lahf)			__( FLAGS -> ah )

			__( these take a one-byte reg or mem operand )
define(flagcarry,setc)
define(flagcarryORoverflow,setbe)
define(flagnocarry,setae)
define(flagnocarryANDnonzero,seta)
define(flagnonzero,setne)
define(flanonzer__Rsignequalsoverflow,setg)
define(flagnooverflow,setno)
define(flagoddparity,setpo)
define(flagoverflow,seto)
define(flagparity,setp)
define(flagpositive,setns)
define(flagsign,sets)
define(flagsignaintoverflow,setl)
define(flagsignequalsoverflow,setge)
define(flagzero,sete)
define(flagzeroANDsignaintoverflow,setle)
define(flagzer__Rsignaintoverflow,setng)

define(fsfar,lfs)
define(gsfar,lgs)
define(testAND,test)
define(testANDb,testb)
define(testsubtract,cmp)			__( op sign-extended,)
define(testsubtractdual,cmpw)		
	__( 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(segmentifsubtract,`rep ; cmps counter,')		__( op a , b )
define(bytesegmentifsubtract,`rep ; cmpsb counter,')		__( op )
define(dualsegmentifsubtract,`rep ; cmpsw counter,')
define(quadsegmentifsubtract,`rep ; cmpsd counter,')
define(storemachinestatusword,`smsw')

define(increasing,cld ;)		__( 2 clocks 
					set segment op direction flag)
define(increment,inc)
define(incrementb,incb)
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(ifnocarry,jae)			__( CF = 0	)
define(ifcarry,jb)			__( carry = 1	) 
define(jbe,`jbe')
define(ifcx0jump,jcxz)			__( cx = 0 	)
define(ifcount0jump,jecxz)		__( ecx = 0 	)
define(ifzero,jz)			__( ZF = 1 	)
define(_no_,jz)				__( ZF = 1 i.e. FALSE	)
define(ifnonzero,jne)			__( ZF0 i.e. TRUE )		

__(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 )		
__(jne,jne)				__( ZF0 )		
__(jno,jno)				__(OF = 0 )	
__(jnp,jnp)				__(!pf )
__(jns,jns)				__(!SF)

define(physical,lea)			__( Non-intel docs are better 
					here. Decompose a memory reference
					into an absolute physical
					address. Cheap 1,2,4,8 multiply. 
					Probably handy with cellsize. )

__(leave,leave)			__( opposite of enter, pascalish stuff. )
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 counter; loop if counter <> 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(trapoverflow,into ;)			__( trap 4 on overflow )
define(priviledge,arpl)			__( adjust RPL field of selector )
define(pullcore,popa ;)			__( 24 clocks )
define(pull,pop )			__( 24 clocks )
define(pullflags,popf ;)
define(pushcore,pusha ;)		__( 18 clocks. Not bad. )
define(pushflags,pushf ;)
__(push,push )
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(rights,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(subtractborrow,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(invertcarry,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(with,`,')

__( 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, 
SCHEME
I leave eax, 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. 
The low 4 debug registers might be usable for system globals. 
Thier disadvantage is that they aren't included in fast pushes. ) 

define(RSI,%esp)		__(` # hardware return stack')
define(PSI,%ebp)		__(` # pointer stack index')
define(SI, %ebx)		__(` # pyte Stack Index ')
define(DSI, %ebx)		__(` # pyte Stack Index ')
define(Size,%edx)		__( Size is actually dl. )

__(Generic Register Name Verbosifications)
define(A,%eax)
define(B,%ebx)
define(C,%ecx)
define(D,%edx)
define(DL,%dl)
define(port,%edx)
define(SP,%esp)
define(counter,%ecx)
define(amount,%cl)
define(dest,%edi)
define(source,%esi)
define(stash,%dr0)


__( bus size )
define(cellsize, 4)
__( contents of stack indices )

define(setsource,
		`copy SI to source'		
)

define(setdest,
		`copy SI to dest'
)

__( sub-primitives, i.e. in-lines. 			)

define(PBUMP, 
	`add $`'4 to  PSI ;')

define(PDROP, 
	`subtract $cellsize to 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(askcells, `cmpb $`'4, %dl' )


define(askextradual, `ifbit $`'1, Size' )


define(askodd, `ifbit $`'0, Size' )


define(quadscounter,
`downshift $`'2, counter'
)


__( pytewise op  call_by_editor template, as a comment here, not a macro.
	template is for "can use counter, source, dest; can't use rep;
	working high pytebyte to low"		
setsource
__( DROP or whatever )
	setdest
	askcells
	ifnonzero noncell_LAB
	return	
noncell_LAB:
	   copy Size to counter
	   askodd
	  ifcarry extradual_LAB 
	   decrement counter
	   add $0 with counter
	  jz done_LAB
extradual_LAB:
	      askextradual
	     ifcarry quadloop_LAB
	      subtract $2,  counter
	     add $0 with counter
	     jz done_LAB
quadloop_LAB: 
quadloop_again_LAB:
        loop quadloop_again_LAB
done_LAB:
)
