فهرست منبع

Added proper support for System V AMD64 ABI for callback functions

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7744 8c9fc860-2736-0410-a75d-ab315db34111
eth.negelef 7 سال پیش
والد
کامیت
942b4efbd7
1فایلهای تغییر یافته به همراه31 افزوده شده و 2 حذف شده
  1. 31 2
      source/FoxIntermediateBackend.Mod

+ 31 - 2
source/FoxIntermediateBackend.Mod

@@ -597,6 +597,7 @@ TYPE
 			isModuleBody: BOOLEAN;
 			parametersSize: LONGINT;
 			position: LONGINT;
+			variable: SyntaxTree.Variable;
 
 			PROCEDURE Signature;
 			VAR parameter: SyntaxTree.Parameter; procedureType: SyntaxTree.ProcedureType; returnType : SyntaxTree.Type;
@@ -739,8 +740,7 @@ TYPE
 
 					IF procedureType.callingConvention # SyntaxTree.OberonCallingConvention THEN
 						registerParameters := backend.NumberParameterRegisters(procedureType.callingConvention);
-						
-						
+
 						(* assumption: registers are passed left to right and left parameters are in registers *)
 						formalParameter := procedureType.firstParameter;
 						WHILE (formalParameter # NIL) & (registerNumber < registerParameters) DO
@@ -769,6 +769,35 @@ TYPE
 					END;
 					pc := ir.pc-1;
 
+					IF SysvABI(procedureType.callingConvention) & (system.addressSize = 64) THEN
+						registerParameters := backend.NumberParameterRegisters(procedureType.callingConvention);
+
+						(* assumption: registers are passed left to right and left parameters are in registers *)
+						formalParameter := procedureType.firstParameter;
+						WHILE (formalParameter # NIL) & (registerNumber < registerParameters) DO
+							IF ~PassInRegister(formalParameter) THEN
+								Error(formalParameter.position,"Calling convention error: cannot be passed as register");
+							ELSE
+								IF formalParameter.type.IsRecordType() THEN
+									ASSERT (formalParameter.kind IN {SyntaxTree.VarParameter, SyntaxTree.ConstParameter});
+									type := addressType;
+								ELSE
+									type := GetType(system, formalParameter.type);
+								END;
+								IntermediateCode.InitParameterRegisterClass(registerClass, backend.ParameterRegister(procedureType.callingConvention, type, registerNumber));
+								src := IntermediateCode.Register(type, registerClass, implementationVisitor.AcquireRegister(type, registerClass));
+								implementationVisitor.currentScope := currentScope;
+								variable := implementationVisitor.GetTemporaryVariable(formalParameter.type,FALSE,FALSE);
+								formalParameter.SetOffset(variable.offsetInBits);
+								IntermediateCode.InitMemory(dest,type,implementationVisitor.fp,ToMemoryUnits(system,formalParameter.offsetInBits));
+								ir.Emit(Mov(Basic.invalidPosition,dest, src));
+								implementationVisitor.ReleaseIntermediateOperand(src);
+								INC(registerNumber);
+								formalParameter := formalParameter.nextParameter;
+							END;
+						END;
+					END;
+
 				END;
 
 				implementationVisitor.tagsAvailable := procedureType.callingConvention = SyntaxTree.OberonCallingConvention;