Browse Source

Fixed alignment of complex numbers passed as parameters

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7779 8c9fc860-2736-0410-a75d-ab315db34111
eth.negelef 7 years ago
parent
commit
e1f7b6c4cb
1 changed files with 16 additions and 3 deletions
  1. 16 3
      source/FoxIntermediateBackend.Mod

+ 16 - 3
source/FoxIntermediateBackend.Mod

@@ -4651,7 +4651,7 @@ TYPE
 
 
 		PROCEDURE PushParameter(expression: SyntaxTree.Expression; parameter: SyntaxTree.Parameter; callingConvention: LONGINT; needsParameterBackup: BOOLEAN; VAR parameterBackup: IntermediateCode.Operand; numberRegister: LONGINT);
 		PROCEDURE PushParameter(expression: SyntaxTree.Expression; parameter: SyntaxTree.Parameter; callingConvention: LONGINT; needsParameterBackup: BOOLEAN; VAR parameterBackup: IntermediateCode.Operand; numberRegister: LONGINT);
 		VAR
 		VAR
-			type, descriptorType, baseType: SyntaxTree.Type;
+			type, descriptorType, baseType, componentType: SyntaxTree.Type;
 			operand, tmpOperand, variableOp, variable2Op: Operand;
 			operand, tmpOperand, variableOp, variable2Op: Operand;
 			baseReg, tmp, dimOp, null, dst: IntermediateCode.Operand;
 			baseReg, tmp, dimOp, null, dst: IntermediateCode.Operand;
 			variable, variable2: SyntaxTree.Variable;
 			variable, variable2: SyntaxTree.Variable;
@@ -5271,8 +5271,21 @@ TYPE
 				ELSE
 				ELSE
 					ASSERT((parameter.kind = SyntaxTree.ValueParameter) OR (parameter.kind = SyntaxTree.ConstParameter));
 					ASSERT((parameter.kind = SyntaxTree.ValueParameter) OR (parameter.kind = SyntaxTree.ConstParameter));
 					Evaluate(expression, operand);
 					Evaluate(expression, operand);
-					Pass((operand.tag)); (* real part *)
-					Pass((operand.op)) (* imaginary part *)
+					componentType := parameter.type.resolved(SyntaxTree.ComplexType).componentType;
+					IF (numberRegister > 0) OR (system.AlignmentOf(system.parameterAlignment,componentType) = system.AlignmentOf(system.variableAlignment,componentType)) THEN
+						Pass((operand.tag)); (* imaginary part *)
+						Pass((operand.op)) (* real part *)
+					ELSE
+						(* pass complex as a whole in order to comply with the variable alignment of its components *)
+						size := ToMemoryUnits(system,system.AlignmentOf(system.parameterAlignment,parameter.type));
+						Emit(Sub(position,sp,sp,IntermediateCode.Immediate(addressType,size)));
+						tmp := sp;
+						IntermediateCode.MakeMemory(tmp,operand.op.type);
+						Emit(Mov(position,tmp,operand.op)); (* real part *)
+						size := ToMemoryUnits(system,system.AlignmentOf(system.variableAlignment,componentType));
+						IntermediateCode.AddOffset(tmp,size);
+						Emit(Mov(position,tmp,operand.tag)); (* imaginary part *)
+					END
 				END
 				END
 			ELSE
 			ELSE
 				IF (parameter.kind = SyntaxTree.ValueParameter) OR (parameter.kind = SyntaxTree.ConstParameter) & ~(parameter.type.resolved IS SyntaxTree.RecordType) & ~(parameter.type.resolved IS SyntaxTree.ArrayType) THEN
 				IF (parameter.kind = SyntaxTree.ValueParameter) OR (parameter.kind = SyntaxTree.ConstParameter) & ~(parameter.type.resolved IS SyntaxTree.RecordType) & ~(parameter.type.resolved IS SyntaxTree.ArrayType) THEN