diff genasm.rhope @ 105:43cc42df26cc

Various compiler improvements
author Mike Pavone <pavone@retrodev.com>
date Tue, 24 Aug 2010 23:22:17 -0400
parents 31f8182f3433
children
line wrap: on
line diff
--- a/genasm.rhope	Wed Aug 11 03:13:28 2010 -0400
+++ b/genasm.rhope	Tue Aug 24 23:22:17 2010 -0400
@@ -1,5 +1,3 @@
-//Import extendlib.rhope
-Import backendutils.rhope
 
 Blueprint Registers
 {
@@ -317,20 +315,6 @@
 	out <- [pointer]Target Size >>
 }
 
-Blueprint X86 Instruction
-{
-	Name
-	Op1
-	Op2
-	Width
-	Extra Offset
-}
-
-X86 Instruction[name, op1, op2, width:out]
-{
-	out <- [[[[[Build["X86 Instruction"]]Name << [name]]Op1 << [op1]]Op2 <<[op2]]Width <<[width]]Extra Offset <<[0]
-}
-
 CAppend[left,right:out]
 {
 	If[[right] = [""]]
@@ -341,589 +325,3 @@
 	}
 }
 
-Inst ASM@X86 Instruction[inst,func:out]
-{
-	If[[[inst]Width >>] = [4]]
-	{
-		regs <- ("eax","ecx","edx","ebx","esi","edi","esp")
-	}{
-		If[[[inst]Width >>] = [2]]
-		{
-			regs <- ("ax","cx","dx","bx","si","di")
-		}{
-			regs <- ("al","cl","dl","bl","si","di")
-		}
-	}
-	out <- [[[inst]Name >>
-	]Append[ [" "]CAppend[[[inst]Op1>>]Op ASM[func, regs, [inst]Extra Offset >>]] ]
-	]Append[ [", "]CAppend[[[inst]Op2>>]Op ASM[func, regs, [inst]Extra Offset >>]] ]
-}
-
-Blueprint X86 Function
-{
-	Name
-	Registers
-	Variables
-	Scratch
-	Need Save
-	Free Stack Locations
-	Stack Size
-	Param Size
-	Temp Stack
-	Convention
-	Instructions
-}
-
-X86 Function[name,params,convention:out]
-{
-	[[[[[[[[[Build["X86 Function"]
-	]Name << [name]
-	]Registers << [Registers[("eax","ecx","edx","ebx","esi","edi"), (0,1,2,3,4,5), (0,1,2,3,4,5), (3,4,5), 4]]
-	]Variables  <<[New@Dictionary[]]
-	]Need Save <<[()]
-	]Free Stack Locations <<[()]
-	]Stack Size <<[0]
-	]Instructions <<[()]
-	]Convention <<[convention]
-	]Alloc Params[params, convention]
-	{
-		out <- [~]Param Size <<[ [~]Stack Size >> ]
-	}
-}
-
-Pointer Size@X86 Function[func:out]
-{
-	out <- 4
-}
-
-Param Helper@X86 Function[func, param:out]
-{
-	,loc <- [func]Allocate Stack[4]
-	{
-		out <- [~]Variables << [ [[~]Variables >>]Set[param, loc] ]
-	}
-}
-
-Alloc Params@X86 Function[func,params,convention:out]
-{
-	If[[convention] = ["fastcall"]]
-	{
-		[params]Index[0]
-		{
-				next func <- [[func]Registers <<[ [[func]Registers >>]Available? <<[ [[[func]Registers >>]Available? >>]Set[1, No] ]]
-				]Variables <<[ [[func]Variables >>]Set[~, Register[1,4]] ]
-				[params]Index[1]
-				{
-					next func2 <- [[next func]Registers <<[ [[next func]Registers >>]Available? <<[ [[[next func]Registers >>]Available? >>]Set[2, No] ]]
-					]Variables <<[ [[next func]Variables >>]Set[~, Register[2,4]] ]
-					[params]Index[2]
-					{
-						out <- _Fold[params, 2, next func2, "Param Helper"]
-					}{
-						out <- Val[next func2]
-					}
-				}{
-					out <- Val[next func]
-				}
-		}{
-			out <- func
-		}
-	}{
-		out <- Fold["Param Helper", func, params]
-	}
-}
-
-Add Instruction@X86 Function[func, inst:out]
-{
-	out <- [func]Instructions << [ [[func]Instructions >>]Append[ [inst]Extra Offset <<[[func]Temp Stack >>] ] ]
-}
-
-Allocate Stack@X86 Function[func,size:func out,out]
-{
-	out <- Stack Location[[func]Stack Size >>, size]
-	func out <- [func]Stack Size <<[ [[func]Stack Size >>]+[size] ]
-}
-
-Allocate Var@X86 Function[func,name,size,type:out func,out]
-{
-	out func, out <- Processor Allocate[func,name,size,type]
-}
-
-Resolve@X86 Function[func,op:out,out func]
-{
-	If[[Type Of[op]] = ["String"]]
-	{
-		out <- [[func]Variables >>]Index[op]
-	}{
-		out <- op
-	}
-}
-
-Allocate Scratch@X86 Function[func,size:out func,scratch]
-{
-	out func,scratch <- Processor Reg[func,"data"] {} {}
-	{
-		//FIXME: need to use a reg that's not involved in the current op
-		//FIXME: Also, might need two scratch regs and both might be in use
-		,stack inc <- [func]Save Reg[0]
-		{
-			out func <- [~]Scratch << [ [[~]Scratch >>]Set[0, Yes] ]
-		}
-	}
-}
-
-Free Scratch@X86 Function[func,scratch:out func]
-{
-	[[func]Scratch >>]Index[scratch]
-	{
-		[func]Restore Reg[scratch]
-		{
-			out func <- [~]Scratch << [ [[~]Scratch >>]Remove[scratch] ]
-		}
-	}{
-		out func <- Processor Free Reg[func, scratch]
-	}
-	If[[scratch]Index[1]]
-	{
-		
-	}{
-		
-	}
-}
-
-Classify Op@X86 Function[func,op:class]
-{
-	If[[op]In Memory?]
-	{
-		If[[Type Of[op]] = ["Pointer"]]
-		{
-			If[[[[op]Base >>]In Memory?] Or [[[op]Offset >>]In Memory?]]
-			{
-				class <- "u"
-			}{
-				class <- "m"
-			}
-		}{
-			class <- "m"
-		}
-	}{
-		class <- "r"
-	}
-}
-
-RegMem2Op@X86 Function[func,dest,notdest,op,size:out]
-{
-	out <- [func]Add Instruction[X86 Instruction[op, dest, notdest, size]]
-}
-
-MemPointer2Op@X86 Function[func,dest,notdest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		out <- [[[~]Fetch[notdest,scratch]
-			]Add Instruction[X86 Instruction[op, dest, scratch, size]]
-			]Free Scratch[scratch]
-	}
-}
-
-//Make sure to map this to both r, (m or r) -> m and r, (m or r) -> r
-RegMemToNotPointer@X86 Function[func,source1,source2,dest,op,size:out]
-{
-	out <- [[func]Move[source2,dest]
-		]Add Instruction[X86 Instruction[op, dest, source1, size]]
-}
-
-RegMemToPointer@X86 Function[func,source1,source2,dest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		spointer <- Pointer[scratch, None[], size]
-		out <- [[[[~]Calculate Address[dest, scratch]
-			]Move[source2, spointer]
-			]Add Instruction[X86 Instruction[op, spointer, source1, size]]
-			]Free Scratch[scratch]
-	}
-}
-
-RegPointerToMem@X86 Function[func,source1,source2,dest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		spointer <- Pointer[scratch, None[], size]
-		out <- [[[[~]Calculate Address[source2, scratch]
-			]Move[spointer, dest]
-			]Add Instruction[X86 Instruction[op, dest, source1, size]]
-			]Free Scratch[scratch]
-	}
-}
-
-RegPointerReg2Op@X86 Function[func,dest,notdest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		spointer <- Pointer[scratch, None[], size]
-		out <- [[[~]Calculate Address[notdest, scratch]
-			]Add Instruction[X86 Instruction[op, dest, spointer, size]]
-			]Free Scratch[scratch]
-	}
-}
-
-RegPointerPointer2Op@X86 Function[func,dest,notdest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		spointer <- Pointer[scratch, None[], size]
-		out <- [[[~]Calculate Address[dest, scratch]
-			]Add Instruction[X86 Instruction[op, spointer, notdest, size]]
-			]Free Scratch[scratch]
-	}
-}
-
-RegPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		spointer <- Pointer[scratch, None[], size]
-		,scratch2 <- [~]Allocate Scratch[size]
-		{
-			spointer2 <- Pointer[scratch2, None[], size]
-			out <- [[[[[[~]Calculate Address[source2, scratch]
-				]Calculate Address[dest, scratch2]
-				]Move[spointer2, spointer]
-				]Add Instruction[X86 Instruction[op, spointer2, source1, size]]
-				]Free Scratch[scratch2]
-				]Free Scratch[scratch]
-		}
-	}
-}
-
-//If source1, source2 and dest are all pointers with register offsets, allocating a scratch register could
-//become a problem unless I let ebp be used as a scratch register. Should be doable as long as thread local
-//variables properly report ebp as a used register. Alternatively, one register could be reserved for scratch
-//usage
-MemPointerToMem@X86 Function[func,source1,source2,dest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		out <- [[[[~]Fetch[source2, scratch]
-			]Add Instruction[X86 Instruction[op, scratch, source1, size]]
-			]Move[scratch, dest]
-			]Free Scratch[scratch]
-	}
-}
-
-MemPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		,scratch2 <- [~]Allocate Scratch[size]
-		{
-			spointer2 <- Pointer[scratch2, None[], size]
-			out <- [[[[[[~]Fetch[source2, scratch]
-				]Add Instruction[X86 Instruction[op, scratch, source1, size]]
-				]Calculate Address[dest, scratch2]
-				]Move[scratch, spointer2]
-				]Free Scratch[scratch2]
-				]Free Scratch[scratch]
-		}
-	}
-}
-
-//This does almost the same thing as RegMemToNotPointer, depending on how I do the pattern matching I could maybe combine them
-PointerMemToReg@X86 Function[func,source1,source2,dest,op,size:out]
-{
-	out <- [[func]Fetch[source1,dest]
-		]Add Instruction[X86 Instruction[op, dest, source2, size]]
-}
-
-PointerPointer2Op@X86 Function[func,dest,notdest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		spointer <- Pointer[scratch, None[], size]
-		,scratch2 <- [~]Allocate Scratch[size]
-		{
-			out <- [[[[[[[~]Calculate Address[dest, scratch]
-				]Fetch[notdest, scratch2]
-				]Add Instruction[X86 Instruction[op, scratch, scratch2, size]]
-				]Calculate Address[dest, scratch2]
-				]Move[scratch, spointer2]
-				]Free Scratch[scratch2]
-				]Free Scratch[scratch]
-		}
-	}
-}
-
-PointerPointerToPointer@X86 Function[func,source1,source2,dest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		,scratch2 <- [~]Allocate Scratch[size]
-		{
-			spointer2 <- Pointer[scratch2, None[], size]
-			out <- [[[[[[[~]Fetch[source1, scratch]
-				]Calculate Address[source2, scratch2]
-				]Add Instruction[X86 Instruction[op, scratch, spointer2, size]]
-				]Calculate Address[dest, scratch2]
-				]Move[scratch, spointer2]
-				]Free Scratch[scratch2]
-				]Free Scratch[scratch]
-		}
-	}
-}
-
-PointerPointerToMem@X86 Function[func,source1,souce2,dest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		spointer <- Pointer[scratch, None[], size]
-		out <- [[[[[~]Calculate Address[source1, scratch]
-			]Move[dest, spointer]
-			]Fetch[source2, scratch]
-			]Add Instruction[X86 Instruction[op, dest, scratch, size]]
-			]Free Scratch[scratch]
-	}
-}
-
-PointerPointerToReg@X86 Function[func,source1,souce2,dest,op,size:out]
-{
-	,scratch <- [func]Allocate Scratch[size]
-	{
-		spointer <- Pointer[scratch, None[], size]
-		out <- [[[[~]Fetch[source1, dest]
-			]Calculate Address[source2, scratch]
-			]Add Instruction[X86 Instruction[op, dest, scratch, size]]
-			]Free Scratch[scratch]
-	}
-}
-
-2Op Associative@X86 Function[func,psource1,psource2,pdest,name:out func]
-{
-	source1 <- [func]Resolve[psource1]
-	source2 <- [func]Resolve[psource2]
-	dest <- [func]Resolve[pdest]
-	dest class <- [func]Classify Op[dest]
-	width <- Min[Min[Min[[source1]Size,[source2]Size], [dest]Size], 4]
-	swapper <- (1,0)
-	sources <- [[()]Append[source1]Append[source2]
-	[sources]Find[dest]
-	{
-		source <- [swapper]Index[~]
-		source class <- [func]Classify Op[source]
-		If[[dest class] = ["u"]]
-		{
-			If[[source class] = ["r"]]
-			{
-				out func <- [func]RegPointerPointer2Op[dest,source,name,width]
-			}{
-				out func <- [func]PointerPointer2Op[dest,source,name,width]
-			}
-		}{
-			If[[dest class] = ["r"]]
-			{
-				If[[source class] = ["u"]]
-				{
-					out func <- [func]RegPointerReg2Op[dest,source,name,width]
-				}{
-					out func <- [func]RegMem2Op[dest,source,name,width]
-				}
-			}{
-				If[[source class] = ["r"]]
-				{
-					out func <- [func]RegMem2Op[dest,source,name,width]
-				}{
-					out func <- [func]MemPointer2Op[dest,source,name,width]
-				}
-			}
-		}
-	}{
-		sclasses <- Map[sources, ["Classify Op"]Set Input[0, func]]
-		first <- [sources]Index[found index]
-		other index <- [swapper]Index[found index]
-		other <- [sources]Index[other index]
-		other class <- [sclasses]Index[other index]
-		found index <- [sclasses]Find["r"]
-		{
-			If[[other class] = ["u"]]
-			{
-				If[[dest class] = ["m"]]
-				{
-					out func <- [func]RegPointerToMem[first,other,dest,name,width]
-				}{
-					If[[dest class] = ["u"]]
-					{
-						out func <- [func]RegPointerToPointer[first,other,dest,name,width]
-					}{
-						out func <- [func]PointerMemToReg[other,first,dest,name,width]
-					}
-				}
-			}{
-				If[[dest class] = ["u"]]
-				{
-					out func <- [func]RegMemToPointer[first,other,dest,name,width]
-				}{
-					out func <- [func]RegMemToNotPointer[first,other,dest,name,width]
-				}
-			}
-		}{
-			found index <- [sclasses]Find["m"]
-			{
-				If[[dest class] = ["r"]]
-				{
-					out func <- [func]PointerMemToReg[other,first,dest,name,width]
-				}{
-					If[[dest class] = ["m"]]
-					{
-						out func <- [func]MemPointerToMem[first,other,dest,name,width]	
-					}{
-						out func <- [func]MemPointerToPointer[first,other,dest,name,width]
-					}
-				}
-			}{
-				If[[dest class] = ["r"]]
-				{
-					out func <- [func]PointerPointerToReg[first,other,dest,name,width]
-				}{
-					If[[dest class] = ["m"]]
-					{
-						out func <- [func]PointerPointerToMem[first,other,dest,name,width]
-					}{
-						out func <- [func]PointerPointerToPointer[first,other,dest,name,width]
-					}
-				}
-			}
-		}
-	}
-}
-
-2Op@X86 Function[func,psource1,psource2,pdest,name:out func]
-{
-	source1 <- [func]Resolve[psource1]
-	source2 <- [func]Resolve[psource2]
-	dest <- [func]Resolve[pdest]
-	width <- Min[Min[Min[[source1]Size,[source2]Size], [dest]Size], 4]
-	If[[source1] = [dest]]
-	{
-		If[[[source1]In Memory?] And [[source2]In Memory?]]
-		{
-			,scratch, stack inc <- [func]Allocate Scratch[width]
-			{
-				out func <- [[[~]Add Instruction[X86 Instruction["mov", [scratch]Index[0], source2, width, stack inc]]
-				]Add Instruction[X86 Instruction[name, source1, [scratch]Index[0], width, stack inc]]
-				]Free Scratch[scratch]
-			}
-		}{
-			out func <- [func]Add Instruction[X86 Instruction[name, dest, source2, width, 0]]
-		}
-	}{
-		If[[dest]In Memory?]
-		{
-			If[[source2]In Memory?]
-			{
-				,scratch, stack inc <- [func]Allocate Scratch[width]
-				{
-					out func <- [[[[~]Add Instruction[X86 Instruction["mov", [scratch]Index[0], source1, width, stack inc]]
-					]Add Instruction[X86 Instruction[name, [scratch]Index[0], source2, width, stack inc]]
-					]Add Instruction[X86 Instruction["mov", dest, [scratch]Index[0], width, stack inc]]
-					]Free Scratch[scratch]
-				}
-			}{
-				out func <- [[func]Move[source1,dest]
-				]Add Instruction[X86 Instruction[name, dest, source2, width, 0]]
-			}
-		}{
-			out func <- [[func]Move[source1,dest]
-			]Add Instruction[X86 Instruction[name, dest, source2, width, 0]]
-		}
-	}
-}
-
-Add@X86 Function[func,source1,source2,dest:out func]
-{
-	out func <- [func]2Op Associative[source1,source2,dest,"add"]
-}
-
-Sub@X86 Function[func,source1,source2,dest:out func]
-{
-	out func <- [func]2Op[source1,source2,dest,"sub"]
-}
-
-Move@X86 Function[func,psource,pdest:out func]
-{
-	source <- [func]Resolve[psource]
-	dest <- [func]Resolve[pdest]
-	out func <- [func]Add Instruction[X86 Instruction["mov", dest, source, 4]]
-}
-
-Instruction ASM[current,instruction,func:out]
-{
-	out <- [[[current]Append["\t"]]Append[ [instruction]Inst ASM[func] ]]Append["\n"]
-}
-
-Save Reg@X86 Function[func,reg:out]
-{
-	out <- [[func]Add Instruction[X86 Instruction["push", Register[reg, 4], None[], 4]]
-	]Temp Stack << [ [[func]Temp Stack >>]+[4] ]
-}
-
-Prolog Save@X86 Function[func,junk,reg:out]
-{
-	out <- [[func]Add Instruction[X86 Instruction["push", Register[reg, 4], None[], 4]]
-	]Stack Size << [ [[func]Stack Size >>]+[4] ]
-}
-
-Restore Reg@X86 Function[func,reg:out]
-{
-	out <- [[func]Add Instruction[X86 Instruction["pop", Register[reg, 4], None[], 4]]
-	]Temp Stack << [ [[func]Temp Stack >>]-[4] ]
-}
-
-Epilogue Restore@X86 Function[func,junk,reg:out]
-{
-	out <- [func]Add Instruction[X86 Instruction["pop", Register[reg, 4], None[], 4]]
-}
-
-Finalize@X86 Function[func:out]
-{
-	alloc stack <- [[func]Stack Size >>] - [[func]Param Size >>]
-	
-	oldstream <- [func]Instructions >>
-	
-	If[[alloc stack] > [0]]
-	{
-		start <- [()]Append[X86 Instruction["sub", Register[6, 4],Immediate[alloc stack], Register[6, 4], 4], func]
-	}{
-		start <- ()
-	}
-	
-	If[[[func]Convention >>] = ["cdecl"]]
-	{
-		If[ [alloc stack] > [0] ]
-		{
-			retparam <- Immediate[alloc stack]
-		}{
-			retparam <- None[]
-		}
-	}{
-		retparam <- Immediate[[func]Stack Size >>]
-	}
-	
-	[[func]Need Save >>]First
-	{
-		prolog <- Fold["Prolog Save", [func]Instructions << [start], [func]Need Save >>]
-		out <- [Reverse Fold["Epilogue Restore", body, [func]Need Save >>]]Add Instruction[X86 Instruction["ret", retparam, None[], 4]]
-	}{
-		prolog <- [func]Instructions <<[start]
-		out <- [body]Add Instruction[X86 Instruction["ret", retparam, None[], 4]]
-	}
-	
-	body <- Fold["Add Instruction", prolog, oldstream]
-}
-
-Text@X86 Function[func:out]
-{
-	name line <- [Escape Rhope Name[[func]Name >>]
-	]Append[":\n"]
-	
-	out <- Fold[["Instruction ASM"]Set Input[2, func], name line, [func]Instructions >>]
-}