Sfoglia il codice sorgente

WinAPI calling convention (shadow registers to stack)

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7413 8c9fc860-2736-0410-a75d-ab315db34111
felixf 7 anni fa
parent
commit
5ba63086f9
2 ha cambiato i file con 49 aggiunte e 19 eliminazioni
  1. 34 10
      source/FoxAMDBackend.Mod
  2. 15 9
      source/FoxIntermediateBackend.Mod

+ 34 - 10
source/FoxAMDBackend.Mod

@@ -487,7 +487,7 @@ TYPE
 		(* static generator state variables, considered constant during generation *)
 		runtimeModuleName: SyntaxTree.IdentifierString;
 		cpuBits: LONGINT;
-		opBP, opSP, opRA, opRB, opRC, opRD, opRS, opR8, opR9: Assembler.Operand; (* base pointer, stack pointer, register A, depends on cpuBits*)
+		opBP, opSP, opRA, opRB, opRC, opRD, opRS, opR8, opR9, opR10, opR11, opR12, opR13, opR14, opR15: Assembler.Operand; (* base pointer, stack pointer, register A, depends on cpuBits*)
 		BP, SP, RA, RD, RS, RC: LONGINT; (* base pointer and stack pointer register index, depends on cpuBits *)
 
 		emitter: Assembler.Emitter; (* assembler generating and containing the machine code *)
@@ -536,6 +536,9 @@ TYPE
 				opBP := opRBP; opSP := opRSP; opRA := registerOperands[RAX]; opRB := registerOperands[RBX]; opRD := registerOperands[RDI];
 				opRS := registerOperands[RSI]; opRC := registerOperands[RCX];
 				opR8 := registerOperands[R8]; opR9 := registerOperands[R9];
+				opR10 := registerOperands[R10]; opR11 := registerOperands[R11];
+				opR12 := registerOperands[R12]; opR13 := registerOperands[R13];
+				opR14 := registerOperands[R14]; opR15 := registerOperands[R15];
 				SP := RSP; BP := RBP; RA := RAX;
 				RD := RDI; RS := RSI; RC := RCX;
 				ASSERT(~error);
@@ -1281,9 +1284,9 @@ TYPE
 					END;
 					IF numberMachineWords >4 THEN
 						Assembler.InitImm(imm, 0, numberMachineWords DIV 4);
-						emitter.Emit2(InstructionSet.opMOV, opRB, imm);
+						emitter.Emit2(InstructionSet.opMOV, opRC, imm); (* is EB register is non-volatile in WINAPI, would ec be better? *)
 						destPC := out.pc;
-						emitter.Emit1(InstructionSet.opDEC, opRB);
+						emitter.Emit1(InstructionSet.opDEC, opRC);
 						emitter.Emit1(InstructionSet.opPUSH, opRA);
 						emitter.Emit1(InstructionSet.opPUSH, opRA);
 						emitter.Emit1(InstructionSet.opPUSH, opRA);
@@ -1309,10 +1312,20 @@ TYPE
 
 			cc := SHORT(instruction.op1.intValue);
 			IF (cc = SyntaxTree.WinAPICallingConvention) OR (cc = SyntaxTree.CCallingConvention) THEN
-				(* the winapi calling convention presumes that all registers except EAX, EDX and ECX are retained by the callee *)
-				emitter.Emit1(InstructionSet.opPUSH,opEBX);
-				emitter.Emit1(InstructionSet.opPUSH,opEDI);
-				emitter.Emit1(InstructionSet.opPUSH,opESI);
+				IF  cpuBits = 32 THEN
+					(* the winapi calling convention presumes that all registers except EAX, EDX and ECX are retained by the callee *)
+					emitter.Emit1(InstructionSet.opPUSH,opEBX);
+					emitter.Emit1(InstructionSet.opPUSH,opEDI);
+					emitter.Emit1(InstructionSet.opPUSH,opESI);
+				ELSE ASSERT(cpuBits =64);
+					emitter.Emit1(InstructionSet.opPUSH,opRB);
+					emitter.Emit1(InstructionSet.opPUSH,opRD);
+					emitter.Emit1(InstructionSet.opPUSH,opRS);
+					emitter.Emit1(InstructionSet.opPUSH,opR12);
+					emitter.Emit1(InstructionSet.opPUSH,opR13);
+					emitter.Emit1(InstructionSet.opPUSH,opR14);
+					emitter.Emit1(InstructionSet.opPUSH,opR15);
+				END;
 			END;
 			spillStackStart := stackSize;
 		END EmitEnter;
@@ -1322,9 +1335,20 @@ TYPE
 		BEGIN
 			cc := SHORT(instruction.op1.intValue);
 			IF (cc = SyntaxTree.WinAPICallingConvention)  OR (cc = SyntaxTree.CCallingConvention) THEN
-				emitter.Emit1(InstructionSet.opPOP,opESI);
-				emitter.Emit1(InstructionSet.opPOP,opEDI);
-				emitter.Emit1(InstructionSet.opPOP,opEBX);
+				IF cpuBits = 32 THEN
+					emitter.Emit1(InstructionSet.opPOP,opESI);
+					emitter.Emit1(InstructionSet.opPOP,opEDI);
+					emitter.Emit1(InstructionSet.opPOP,opEBX);
+				ELSE ASSERT(cpuBits =64);
+					emitter.Emit1(InstructionSet.opPOP,opR15);
+					emitter.Emit1(InstructionSet.opPOP,opR14);
+					emitter.Emit1(InstructionSet.opPOP,opR13);
+					emitter.Emit1(InstructionSet.opPOP,opR12);
+					emitter.Emit1(InstructionSet.opPOP,opRS);
+					emitter.Emit1(InstructionSet.opPOP,opRD);
+					emitter.Emit1(InstructionSet.opPOP,opRB);
+				END;
+				
 			END;
 		END EmitLeave;
 

+ 15 - 9
source/FoxIntermediateBackend.Mod

@@ -730,10 +730,6 @@ TYPE
 					ir.Emit(Nop(position)); (* placeholder for stack frame check *)
 					ir.Emit(Nop(position)); (* placeholder for stack frame check (2) *)
 					*)
-					IF ~procedureType.noPAF THEN (* no procedure activation frame ! *)
-						implementationVisitor.EmitEnter(ir,x.position,x,cc,ToMemoryUnits(system,stackSize),registerNumber);
-					END;
-					pc := ir.pc-1;
 					(*
 					ir.Emit(Nop(position)); (* placeholder for fill *)
 					*)
@@ -758,7 +754,7 @@ TYPE
 									type := GetType(system, formalParameter.type);
 								END;
 								src := IntermediateCode.Register(type, registerClass, implementationVisitor.AcquireRegister(type, registerClass));
-								IntermediateCode.InitMemory(dest,type,implementationVisitor.fp,ToMemoryUnits(system,formalParameter.offsetInBits));
+								IntermediateCode.InitMemory(dest,type,implementationVisitor.sp,ToMemoryUnits(system,formalParameter.offsetInBits - system.addressSize));
 								ir.Emit(Mov(Basic.invalidPosition,dest, src));
 								implementationVisitor.ReleaseIntermediateOperand(src);
 								INC(registerNumber);
@@ -766,6 +762,12 @@ TYPE
 							END;
 						END;
 					END;
+					
+					IF ~procedureType.noPAF THEN (* no procedure activation frame ! *)
+						implementationVisitor.EmitEnter(ir,x.position,x,cc,ToMemoryUnits(system,stackSize),registerNumber);
+					END;
+					pc := ir.pc-1;
+
 				END;
 
 				implementationVisitor.tagsAvailable := procedureType.callingConvention = SyntaxTree.OberonCallingConvention;
@@ -12773,8 +12775,8 @@ TYPE
 			Symbol(section,section,2,0);
 			(*
 				TypeDesc* = POINTER TO RECORD   (* ug: adapt constant TypeDescRecSize if this type is changed !!! *)
-					descSize: LONGINT;
-					sentinel: LONGINT;	(* = MPO-4 *)
+					descSize: SIZE;
+					sentinel: ADDRESS;	(* = MPO-4 *)
 					tag*: ADDRESS; (* pointer to static type descriptor, only used by linker and loader *)
 					flags*: SET;
 					mod*: Module;	(* hint only, because module may have been freed (at Heaps.ModOfs) *)
@@ -12782,9 +12784,10 @@ TYPE
 				END;
 			*)
 			Size(section, 0);
-			Longint(section,0);
+			Address(section,0);
 			Address(section,0);
 			Set(section,{});
+			IF module.system.addressType.sizeInBits = 64 THEN Longint(section, 0); END;
 			moduleSection := ModuleSection();
 			Symbol( section, moduleSection, moduleSection.pc,0);
 			IF procedureSection.symbol = NIL THEN 
@@ -12985,6 +12988,7 @@ TYPE
 					Info(source, "type flags");
 					flags := {};
 					Set( source, flags);
+					
 					Info(source, "pointer to module");
 					moduleSection := ModuleSection();
 					Symbol( source, moduleSection, moduleSection.pc,0);
@@ -13220,6 +13224,8 @@ TYPE
 					flags := {};
 					IF isProtected THEN INCL(flags,31) END;
 					Set( source, flags);
+					IF module.system.addressType.sizeInBits = 64 THEN Longint(source, 0); END;
+
 					Info(source, "pointer to module");
 					moduleSection := ModuleSection();
 					Symbol( source, moduleSection, moduleSection.pc,0);
@@ -14646,7 +14652,7 @@ END FoxIntermediateBackend.
 
 Compiler.Compile -p=Win32G FoxIntermediateBackend.Mod ~
 
-#	Release.Build --path="/temp/obg/"  WinAosNewObjectFile ~
+#	Release.Build --path="/temp/obg/"  IinAosNewObjectFile ~
 #	StaticLinker.Link --fileFormat=PE32 --fileName=A2Z.exe --extension=GofW --displacement=401000H --path="/temp/obg/" Runtime Trace Kernel32 Machine Heaps Modules Objects Kernel KernelLog Streams Commands Files WinFS Clock Dates Reals Strings Diagnostics BitSets StringPool ObjectFile GenericLinker Reflection  GenericLoader  BootConsole ~
 
 #	Release.Build --path="/temp/obg/" WinAosNewObjectFile ~