Quellcode durchsuchen

patched bug with unintended sign extension for 32 bit values being pushed as 64 bit values

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@8341 8c9fc860-2736-0410-a75d-ab315db34111
felixf vor 6 Jahren
Ursprung
Commit
9a03fec8fa
2 geänderte Dateien mit 22 neuen und 4 gelöschten Zeilen
  1. 10 4
      source/FoxAMDBackend.Mod
  2. 12 0
      source/Oberon.Execution.Test

+ 10 - 4
source/FoxAMDBackend.Mod

@@ -872,7 +872,7 @@ TYPE
 			END;
 			END;
 		END GetImmediateMem;
 		END GetImmediateMem;
 
 
-		PROCEDURE GetImmediate(CONST virtual: IntermediateCode.Operand; part: LONGINT; VAR physical: Assembler.Operand; forbidden16Bit: BOOLEAN);
+		PROCEDURE GetImmediate(CONST virtual: IntermediateCode.Operand; part: LONGINT; VAR physical: Assembler.Operand; forbidden16Bit,push: BOOLEAN);
 		VAR type: IntermediateCode.Type; temp: Assembler.Operand; size: SHORTINT; value: HUGEINT;
 		VAR type: IntermediateCode.Type; temp: Assembler.Operand; size: SHORTINT; value: HUGEINT;
 
 
 			PROCEDURE IsImm8(value: HUGEINT): BOOLEAN;
 			PROCEDURE IsImm8(value: HUGEINT): BOOLEAN;
@@ -890,6 +890,12 @@ TYPE
 				value := value DIV 10000H DIV 10000H;
 				value := value DIV 10000H DIV 10000H;
 				RETURN (value = 0) OR (value=-1);
 				RETURN (value = 0) OR (value=-1);
 			END IsImm32;
 			END IsImm32;
+			
+			PROCEDURE IsSignedImm32(value: HUGEINT): BOOLEAN;
+			BEGIN
+				RETURN (value <= MAX(SIGNED32)) & (value >= MIN(SIGNED32));
+			END IsSignedImm32;
+			
 
 
 		BEGIN
 		BEGIN
 			ASSERT(virtual.mode = IntermediateCode.ModeImmediate);
 			ASSERT(virtual.mode = IntermediateCode.ModeImmediate);
@@ -910,7 +916,7 @@ TYPE
 				END;
 				END;
 				Assembler.InitImm(physical,size ,value);
 				Assembler.InitImm(physical,size ,value);
 				IF virtual.symbol.name # "" THEN Assembler.SetSymbol(physical,virtual.symbol.name,virtual.symbol.fingerprint,virtual.symbolOffset,virtual.offset+part*Assembler.bits32) END;
 				IF virtual.symbol.name # "" THEN Assembler.SetSymbol(physical,virtual.symbol.name,virtual.symbol.fingerprint,virtual.symbolOffset,virtual.offset+part*Assembler.bits32) END;
-				IF (cpuBits=64) & ((physical.sizeInBytes=8) OR ~IsImm32(value)) THEN
+				IF (cpuBits=64) & ((physical.sizeInBytes=8) OR ~IsImm32(value) OR push & ~IsSignedImm32(value)) THEN
 					ASSERT(cpuBits=64);
 					ASSERT(cpuBits=64);
 					GetTemporaryRegister(IntermediateCode.int64,temp);
 					GetTemporaryRegister(IntermediateCode.int64,temp);
 					emitter.Emit2(InstructionSet.opMOV,temp,physical);
 					emitter.Emit2(InstructionSet.opMOV,temp,physical);
@@ -1032,7 +1038,7 @@ TYPE
 			CASE vop.mode OF
 			CASE vop.mode OF
 				IntermediateCode.ModeMemory: GetMemory(vop,part,op);
 				IntermediateCode.ModeMemory: GetMemory(vop,part,op);
 				|IntermediateCode.ModeRegister:	GetRegister(vop,part,op,ticket);
 				|IntermediateCode.ModeRegister:	GetRegister(vop,part,op,ticket);
-				|IntermediateCode.ModeImmediate: GetImmediate(vop,part,op,FALSE);
+				|IntermediateCode.ModeImmediate: GetImmediate(vop,part,op,FALSE,FALSE);
 			END;
 			END;
 			IF ticket # NIL THEN
 			IF ticket # NIL THEN
 				TicketToOperand(ticket, tmp);
 				TicketToOperand(ticket, tmp);
@@ -2952,7 +2958,7 @@ TYPE
 			ASSERT(type.form IN IntermediateCode.Integer);
 			ASSERT(type.form IN IntermediateCode.Integer);
 
 
 			IF	vop.mode = IntermediateCode.ModeImmediate THEN (* may not push 16 bit immediate: strange instruction in 32 / 64 bit mode *)
 			IF	vop.mode = IntermediateCode.ModeImmediate THEN (* may not push 16 bit immediate: strange instruction in 32 / 64 bit mode *)
-				GetImmediate(vop,part,op1,TRUE);
+				GetImmediate(vop,part,op1,TRUE,TRUE);
 				emitter.Emit1(InstructionSet.opPUSH,op1);
 				emitter.Emit1(InstructionSet.opPUSH,op1);
 			ELSIF (type.sizeInBits = cpuBits) THEN
 			ELSIF (type.sizeInBits = cpuBits) THEN
 				MakeOperand(vop,part,op1,NIL);
 				MakeOperand(vop,part,op1,NIL);

+ 12 - 0
source/Oberon.Execution.Test

@@ -7801,3 +7801,15 @@ positive: pass three-dimensional arrays A[x,y,z] with missing dimensions, e.g. A
 		Test;
 		Test;
 	END Test.
 	END Test.
 
 
+positive: check push of UNSIGNED constants
+
+	MODULE Test;
+		PROCEDURE Check(value: HUGEINT);
+		BEGIN
+			ASSERT(value>0);
+		END Check;
+		
+	BEGIN
+		Check(MAX(UNSIGNED16)); 
+		Check(MAX(UNSIGNED32));
+	END Test.