Pārlūkot izejas kodu

Fixed alignment of ranges passed as parameters

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@8329 8c9fc860-2736-0410-a75d-ab315db34111
negelef 6 gadi atpakaļ
vecāks
revīzija
886244f9cf
1 mainītis faili ar 22 papildinājumiem un 6 dzēšanām
  1. 22 6
      source/FoxIntermediateBackend.Mod

+ 22 - 6
source/FoxIntermediateBackend.Mod

@@ -5381,9 +5381,24 @@ 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.extra)); (* step *)
-					Pass((operand.tag)); (* last *)
-					Pass((operand.op)) (* first *)
+					IF (numberRegister > 0) OR (system.AlignmentOf(system.parameterAlignment,system.lenType) = system.AlignmentOf(system.variableAlignment,system.lenType)) THEN
+						Pass((operand.extra)); (* step *)
+						Pass((operand.tag)); (* last *)
+						Pass((operand.op)); (* first *)
+					ELSE
+						(* pass range as structure in order to comply with the variable alignment of its components *)
+						size := ToMemoryUnits(system,system.AlignedSizeOf(parameter.type));
+						Basic.Align(size,ToMemoryUnits(system,system.AlignmentOf(system.parameterAlignment,system.lenType)));
+						Emit(Sub(position,sp,sp,IntermediateCode.Immediate(addressType,size)));
+						tmp := sp;
+						IntermediateCode.MakeMemory(tmp,operand.op.type);
+						Emit(Mov(position,tmp,operand.op)); (* first *)
+						size := ToMemoryUnits(system,system.AlignedSizeOf(system.lenType));
+						IntermediateCode.AddOffset(tmp,size);
+						Emit(Mov(position,tmp,operand.tag)); (* last *)
+						IntermediateCode.AddOffset(tmp,size);
+						Emit(Mov(position,tmp,operand.extra)); (* step *)
+					END;
 				END
 				END
 			ELSIF parameter.type.resolved IS SyntaxTree.ComplexType THEN
 			ELSIF parameter.type.resolved IS SyntaxTree.ComplexType THEN
 				IF parameter.kind = SyntaxTree.VarParameter THEN
 				IF parameter.kind = SyntaxTree.VarParameter THEN
@@ -5397,13 +5412,14 @@ TYPE
 						Pass((operand.tag)); (* imaginary part *)
 						Pass((operand.tag)); (* imaginary part *)
 						Pass((operand.op)) (* real part *)
 						Pass((operand.op)) (* real part *)
 					ELSE
 					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));
+						(* pass complex as structure in order to comply with the variable alignment of its components *)
+						size := ToMemoryUnits(system,system.AlignedSizeOf(parameter.type));
+						Basic.Align(size,ToMemoryUnits(system,system.AlignmentOf(system.parameterAlignment,componentType)));
 						Emit(Sub(position,sp,sp,IntermediateCode.Immediate(addressType,size)));
 						Emit(Sub(position,sp,sp,IntermediateCode.Immediate(addressType,size)));
 						tmp := sp;
 						tmp := sp;
 						IntermediateCode.MakeMemory(tmp,operand.op.type);
 						IntermediateCode.MakeMemory(tmp,operand.op.type);
 						Emit(Mov(position,tmp,operand.op)); (* real part *)
 						Emit(Mov(position,tmp,operand.op)); (* real part *)
-						size := ToMemoryUnits(system,system.AlignmentOf(system.variableAlignment,componentType));
+						size := ToMemoryUnits(system,system.AlignedSizeOf(componentType));
 						IntermediateCode.AddOffset(tmp,size);
 						IntermediateCode.AddOffset(tmp,size);
 						Emit(Mov(position,tmp,operand.tag)); (* imaginary part *)
 						Emit(Mov(position,tmp,operand.tag)); (* imaginary part *)
 					END
 					END