Browse Source

Interoperability between runtime and modules with or without FPU32 or FPU64 support
Made sure that conversion HUGEINT -> REAL/LONGREAL uses Runtime (before it was just truncating the hugeint which is wrong)

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@6775 8c9fc860-2736-0410-a75d-ab315db34111

felixf 9 years ago
parent
commit
3d3c819260
3 changed files with 82 additions and 19 deletions
  1. 61 10
      source/ARM.ARMRuntime.Mod
  2. 6 4
      source/ARM.FPE64.Mod
  3. 15 5
      source/FoxARMBackend.Mod

+ 61 - 10
source/ARM.ARMRuntime.Mod

@@ -6,14 +6,17 @@ CONST
 	C = 800000H;
 	C = 800000H;
 	E = 100H;
 	E = 100H;
 	S = LONGINT(80000000H); (* used by VFP unit emulation *)
 	S = LONGINT(80000000H); (* used by VFP unit emulation *)
-	MAXREAL = LONGINT(7F7FFFFFH);
+	MAXFLOAT32 = LONGINT(7F7FFFFFH);
 
 
 TYPE
 TYPE
 	ULONGINT = LONGINT; (* alias to make distinction between signed and unsigned more clear *)
 	ULONGINT = LONGINT; (* alias to make distinction between signed and unsigned more clear *)
 	UHUGEINT = HUGEINT;
 	UHUGEINT = HUGEINT;
 	FLOAT32 = LONGINT; (* alias to make clear that the integer actually contains a IEEE 32 bit float *)
 	FLOAT32 = LONGINT; (* alias to make clear that the integer actually contains a IEEE 32 bit float *)
 	FLOAT64= HUGEINT;
 	FLOAT64= HUGEINT;
-
+	DoubleWord = RECORD
+		low*: UNSIGNED32; high*: SIGNED32;
+	END;
+		
 	PROCEDURE DivS8*(left, right: SHORTINT): SHORTINT;
 	PROCEDURE DivS8*(left, right: SHORTINT): SHORTINT;
 	VAR result, dummy: LONGINT;
 	VAR result, dummy: LONGINT;
 	BEGIN	 DivModS32(left, right, result, dummy); RETURN SHORTINT(result)
 	BEGIN	 DivModS32(left, right, result, dummy); RETURN SHORTINT(result)
@@ -322,18 +325,21 @@ TYPE
 	*)
 	*)
 	END DivModU64;
 	END DivModU64;
 
 
+	(* only called when no FPU64 is available *)
 	PROCEDURE NegF32*(float: FLOAT32): FLOAT32;
 	PROCEDURE NegF32*(float: FLOAT32): FLOAT32;
 	CODE
 	CODE
 		LDR R0, [FP, #+float] ; R0 := float
 		LDR R0, [FP, #+float] ; R0 := float
 		EOR R0, R0, #S ; invert only the sign bit
 		EOR R0, R0, #S ; invert only the sign bit
 	END NegF32;
 	END NegF32;
 
 
+	(* only called when no FPU64 is available *)
 	PROCEDURE AbsF32*(float: FLOAT32): FLOAT32;
 	PROCEDURE AbsF32*(float: FLOAT32): FLOAT32;
 	CODE
 	CODE
 		LDR R0, [FP, #+float] ; R0 := float
 		LDR R0, [FP, #+float] ; R0 := float
 		BIC R0, R0, #S ; clear the sign bit
 		BIC R0, R0, #S ; clear the sign bit
 	END AbsF32;
 	END AbsF32;
 
 
+	(* only called when no FPU32 is available *)
 	PROCEDURE AddF32*(x, y: FLOAT32): FLOAT32;
 	PROCEDURE AddF32*(x, y: FLOAT32): FLOAT32;
 	VAR xe, ye, s: LONGINT;
 	VAR xe, ye, s: LONGINT;
 	BEGIN
 	BEGIN
@@ -359,7 +365,7 @@ TYPE
 					WHILE x < C DO x := 2*x; DEC(xe) END
 					WHILE x < C DO x := 2*x; DEC(xe) END
 				END ;
 				END ;
 				IF xe < 0 THEN x := 0  (*underflow*)
 				IF xe < 0 THEN x := 0  (*underflow*)
-				ELSIF xe > 0FEH THEN x := MAXREAL + s; (* overflow *)
+				ELSIF xe > 0FEH THEN x := MAXFLOAT32 + s; (* overflow *)
 				ELSE x := xe*C + (x - C) + s;
 				ELSE x := xe*C + (x - C) + s;
 				END;
 				END;
 			END
 			END
@@ -367,31 +373,37 @@ TYPE
 		RETURN x
 		RETURN x
 	END AddF32;
 	END AddF32;
 	
 	
+	(* only called when no FPU64 is available *)
 	PROCEDURE AddF64*(x,y: FLOAT64): FLOAT64;
 	PROCEDURE AddF64*(x,y: FLOAT64): FLOAT64;
 	VAR z: FLOAT64;
 	VAR z: FLOAT64;
 	BEGIN FPE64.Add(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,y),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	BEGIN FPE64.Add(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,y),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	END AddF64;
 	END AddF64;
 
 
+	(* only called when no FPU64 is available *)
 	PROCEDURE MulF64*(x,y: FLOAT64): FLOAT64;
 	PROCEDURE MulF64*(x,y: FLOAT64): FLOAT64;
 	VAR z: FLOAT64;
 	VAR z: FLOAT64;
 	BEGIN FPE64.Mul(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,y),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	BEGIN FPE64.Mul(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,y),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	END MulF64;
 	END MulF64;
 
 
+	(* only called when no FPU64 is available *)
 	PROCEDURE DivF64*(x,y: FLOAT64): FLOAT64;
 	PROCEDURE DivF64*(x,y: FLOAT64): FLOAT64;
 	VAR z: FLOAT64;
 	VAR z: FLOAT64;
 	BEGIN FPE64.Div(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,y),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	BEGIN FPE64.Div(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,y),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	END DivF64;
 	END DivF64;
 
 
+	(* only called when no FPU64 is available *)
 	PROCEDURE SubF64*(x,y: FLOAT64): FLOAT64;
 	PROCEDURE SubF64*(x,y: FLOAT64): FLOAT64;
 	VAR z: FLOAT64;
 	VAR z: FLOAT64;
 	BEGIN FPE64.Sub(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,y),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	BEGIN FPE64.Sub(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,y),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	END SubF64;
 	END SubF64;
 
 
+	(* only called when no FPU64 is available *)
 	PROCEDURE AbsF64*(x: FLOAT64): FLOAT64;
 	PROCEDURE AbsF64*(x: FLOAT64): FLOAT64;
 	VAR z: FLOAT64;
 	VAR z: FLOAT64;
 	BEGIN FPE64.Abs(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	BEGIN FPE64.Abs(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	END AbsF64;
 	END AbsF64;
 
 
+	(* only called when no FPU64 is available *)
 	PROCEDURE NegF64*(x: FLOAT64): FLOAT64;
 	PROCEDURE NegF64*(x: FLOAT64): FLOAT64;
 	VAR z: FLOAT64;
 	VAR z: FLOAT64;
 	BEGIN FPE64.Neg(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	BEGIN FPE64.Neg(SYSTEM.VAL(FPE64.Float64,x),SYSTEM.VAL(FPE64.Float64,z)); RETURN z
@@ -412,50 +424,77 @@ TYPE
 		RETURN FPE64.FixInt64(d)
 		RETURN FPE64.FixInt64(d)
 	END ConvS64F32;
 	END ConvS64F32;
 
 
+	(* only called when no FPU32 is available *)
 	PROCEDURE ConvF32F64*(x: FLOAT64): FLOAT32;
 	PROCEDURE ConvF32F64*(x: FLOAT64): FLOAT32;
-	BEGIN RETURN SYSTEM.VAL(FLOAT32, FPE64.Single(SYSTEM.VAL(FPE64.Float64,x)))
+	BEGIN RETURN FPE64.Single(SYSTEM.VAL(FPE64.Float64,x))
 	END ConvF32F64;
 	END ConvF32F64;
 
 
-	PROCEDURE ConvF64F32*(x: REAL): FLOAT64;
+	(* if an FPU32 is available, the result must be made available via FPU register *)
+	PROCEDURE ConvF32F64F*(x: FLOAT64): REAL;
+	VAR r: FLOAT32;
+	BEGIN 
+		r := FPE64.Single(SYSTEM.VAL(FPE64.Float64,x));
+		RETURN SYSTEM.VAL(REAL, r);
+	END ConvF32F64F;
+
+	(* only called when no FPU64 is available *)
+	PROCEDURE ConvF64F32*(x: FLOAT32): FLOAT64;
 	VAR z: FLOAT64;
 	VAR z: FLOAT64;
 	BEGIN FPE64.Double(x,SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	BEGIN FPE64.Double(x,SYSTEM.VAL(FPE64.Float64,z)); RETURN z
 	END ConvF64F32;
 	END ConvF64F32;
 
 
+	(* only called when no FPU64 is available *)
 	PROCEDURE ConvF64S64*(x: HUGEINT): FLOAT64;
 	PROCEDURE ConvF64S64*(x: HUGEINT): FLOAT64;
 	VAR flt: FLOAT64;
 	VAR flt: FLOAT64;
 	BEGIN
 	BEGIN
 		FPE64.FloatInt64(x, SYSTEM.VAL(FPE64.Float64, flt)); RETURN flt
 		FPE64.FloatInt64(x, SYSTEM.VAL(FPE64.Float64, flt)); RETURN flt
 	END ConvF64S64;
 	END ConvF64S64;
 
 
+	(* if an FPU64 is available, the result must be made available via FPU register *)
+	PROCEDURE ConvF64S64F*(x: DoubleWord): LONGREAL;
+	VAR l,h:LONGREAL;
+	BEGIN
+		l := x.low;
+		h := x.high;
+		RETURN  h * 100000000H + l;
+	END ConvF64S64F;
+
+	(* only called when no FPU64 is available *)
 	PROCEDURE ConvF64S32*(x: LONGINT): FLOAT64;
 	PROCEDURE ConvF64S32*(x: LONGINT): FLOAT64;
 	VAR flt: FLOAT64;
 	VAR flt: FLOAT64;
 	BEGIN FPE64.Float(x, SYSTEM.VAL(FPE64.Float64,flt)); RETURN flt
 	BEGIN FPE64.Float(x, SYSTEM.VAL(FPE64.Float64,flt)); RETURN flt
 	END ConvF64S32;
 	END ConvF64S32;
 
 
+	(* only called when no FPU64 is available *)
 	PROCEDURE ConvF64S16*(x: INTEGER): FLOAT64;
 	PROCEDURE ConvF64S16*(x: INTEGER): FLOAT64;
 	VAR flt: FLOAT64;
 	VAR flt: FLOAT64;
 	BEGIN FPE64.Float(x, SYSTEM.VAL(FPE64.Float64,flt)); RETURN flt
 	BEGIN FPE64.Float(x, SYSTEM.VAL(FPE64.Float64,flt)); RETURN flt
 	END ConvF64S16;
 	END ConvF64S16;
 
 
-	PROCEDURE ConvF32S16*(x: INTEGER): REAL;
+	(* only called when no FPU32 is available *)
+	PROCEDURE ConvF32S16*(x: INTEGER): FLOAT32;
 	BEGIN
 	BEGIN
 		RETURN ConvF32S32(LONGINT(x))
 		RETURN ConvF32S32(LONGINT(x))
 	END ConvF32S16;
 	END ConvF32S16;
 	
 	
-	PROCEDURE ConvF32S8*(x: SHORTINT): REAL;
+	(* only called when no FPU32 is available *)
+	PROCEDURE ConvF32S8*(x: SHORTINT): FLOAT32;
 	BEGIN
 	BEGIN
 		RETURN ConvF32S16(INTEGER(x))
 		RETURN ConvF32S16(INTEGER(x))
 	END ConvF32S8;
 	END ConvF32S8;
 	
 	
+	(* only called when no FPU64 is available *)
 	PROCEDURE ConvF64S8*(x: SHORTINT): FLOAT64;
 	PROCEDURE ConvF64S8*(x: SHORTINT): FLOAT64;
 	BEGIN
 	BEGIN
 		RETURN ConvF64S16(INTEGER(x))
 		RETURN ConvF64S16(INTEGER(x))
 	END ConvF64S8;
 	END ConvF64S8;
 
 
+	(* only called when no FPU32 is available *)
 	PROCEDURE SubF32*(left, right: FLOAT32): FLOAT32;
 	PROCEDURE SubF32*(left, right: FLOAT32): FLOAT32;
 	BEGIN RETURN AddF32(left, NegF32(right))
 	BEGIN RETURN AddF32(left, NegF32(right))
 	END SubF32;
 	END SubF32;
 
 
+	(* only called when no FPU32 is available *)
 	PROCEDURE MulF32*(x, y: FLOAT32): FLOAT32;
 	PROCEDURE MulF32*(x, y: FLOAT32): FLOAT32;
 	VAR xe, zh, ye, s: LONGINT;  (*zh, ye in this order; ye used as zh in MULD*)
 	VAR xe, zh, ye, s: LONGINT;  (*zh, ye in this order; ye used as zh in MULD*)
 	BEGIN
 	BEGIN
@@ -479,7 +518,7 @@ TYPE
 			IF xe < 0 THEN (* underflow *)
 			IF xe < 0 THEN (* underflow *)
 				x := 0;
 				x := 0;
 			ELSIF xe > 0FEH THEN (* overflow *)
 			ELSIF xe > 0FEH THEN (* overflow *)
-				x := MAXREAL + s;
+				x := MAXFLOAT32 + s;
 			ELSE
 			ELSE
 				x := xe*C + (x-C) + s;
 				x := xe*C + (x-C) + s;
 			END;
 			END;
@@ -487,12 +526,13 @@ TYPE
 		RETURN x
 		RETURN x
 	END MulF32;
 	END MulF32;
 	
 	
+	(* only called when no FPU32 is available *)
 	PROCEDURE DivF32*(x, y: FLOAT32): FLOAT32;
 	PROCEDURE DivF32*(x, y: FLOAT32): FLOAT32;
 	VAR xe, ye, q, s: LONGINT;
 	VAR xe, ye, q, s: LONGINT;
 	BEGIN
 	BEGIN
 		s := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.XOR(x, y))*{31});
 		s := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.XOR(x, y))*{31});
 		IF SYSTEM.NULL(y) = TRUE THEN
 		IF SYSTEM.NULL(y) = TRUE THEN
-			x := MAXREAL + s;
+			x := MAXFLOAT32 + s;
 		ELSIF SYSTEM.NULL(x) = FALSE THEN
 		ELSIF SYSTEM.NULL(x) = FALSE THEN
 			xe := x DIV C MOD E; (* exponent with bias *)
 			xe := x DIV C MOD E; (* exponent with bias *)
 			ye := y DIV C MOD E; (* exponent with bias *)
 			ye := y DIV C MOD E; (* exponent with bias *)
@@ -505,7 +545,7 @@ TYPE
 			IF xe < 0 THEN (* underflow *)
 			IF xe < 0 THEN (* underflow *)
 				x := 0;
 				x := 0;
 			ELSIF xe > 0FEH THEN (* overflow *)
 			ELSIF xe > 0FEH THEN (* overflow *)
-				x := MAXREAL + s;
+				x := MAXFLOAT32 + s;
 			ELSE (* divide *)
 			ELSE (* divide *)
 				q := 0;
 				q := 0;
 				WHILE q < LONGINT(1000000H) DO (* 2*C *)
 				WHILE q < LONGINT(1000000H) DO (* 2*C *)
@@ -545,6 +585,7 @@ TYPE
 	(** converts an integer into a float, ignores the non-integer part
 	(** converts an integer into a float, ignores the non-integer part
 	- corresponds to REAL(int)
 	- corresponds to REAL(int)
 	- note that no rounding occurs
 	- note that no rounding occurs
+	only called when no FPU32 is available
 	**)
 	**)
 	PROCEDURE ConvF32S32*(x: LONGINT): FLOAT32;
 	PROCEDURE ConvF32S32*(x: LONGINT): FLOAT32;
 	VAR xe, s: LONGINT;
 	VAR xe, s: LONGINT;
@@ -566,11 +607,21 @@ TYPE
 		RETURN x
 		RETURN x
 	END ConvF32S32;
 	END ConvF32S32;
 
 
+	(* only called when no FPU32 is available *)
 	PROCEDURE ConvF32S64*(x: HUGEINT): FLOAT32;
 	PROCEDURE ConvF32S64*(x: HUGEINT): FLOAT32;
 	BEGIN
 	BEGIN
 		RETURN ConvF32F64(ConvF64S64(x))
 		RETURN ConvF32F64(ConvF64S64(x))
 	END ConvF32S64;
 	END ConvF32S64;
 
 
+	(* if an FPU32 is available, the result must be made available via FPU register *)
+	PROCEDURE ConvF32S64F*(x: DoubleWord): REAL;
+	VAR l,h:REAL;
+	BEGIN
+		l := x.low;
+		h := x.high;
+		RETURN  h * 100000000H + l;
+	END ConvF32S64F;
+
 	(* ---- STRING OPERATIONS ---- *)
 	(* ---- STRING OPERATIONS ---- *)
 
 
 	(** compare two strings
 	(** compare two strings

+ 6 - 4
source/ARM.FPE64.Mod

@@ -9,6 +9,8 @@ MODULE FPE64;
 		Float64* = RECORD
 		Float64* = RECORD
 			low*, high*: LONGINT
 			low*, high*: LONGINT
 		END;
 		END;
+		
+		Float32* = LONGINT;
 
 
 	PROCEDURE Addd(VAR x1, x0: LONGINT; y1, y0: LONGINT);
 	PROCEDURE Addd(VAR x1, x0: LONGINT; y1, y0: LONGINT);
 	CODE
 	CODE
@@ -505,8 +507,9 @@ MODULE FPE64;
 		RETURN x1
 		RETURN x1
 	END Fix;
 	END Fix;
 
 
-	PROCEDURE Single*(VAR a: Float64): REAL;
-		VAR x0, x1, s, xe, m, i: LONGINT; x: REAL;
+	(* do not return floating point values in a register: on platforms supporting FPU this will be misinterpreted *)
+	PROCEDURE Single*(VAR a: Float64): Float32;
+		VAR x0, x1, s, xe, m: LONGINT; i: Float32;
 	BEGIN
 	BEGIN
 		x0 := a.low;
 		x0 := a.low;
 		x1 := a.high;
 		x1 := a.high;
@@ -524,8 +527,7 @@ MODULE FPE64;
 			(* make short float value *)
 			(* make short float value *)
 			i := xe*800000H + m + s;
 			i := xe*800000H + m + s;
 		END;
 		END;
-		SYSTEM.PUT32(ADDRESSOF(x), i);
-		RETURN x
+		RETURN i;
 	END Single;
 	END Single;
 
 
 	PROCEDURE Double*(x: REAL; VAR z: Float64);
 	PROCEDURE Double*(x: REAL; VAR z: Float64);

+ 15 - 5
source/FoxARMBackend.Mod

@@ -101,7 +101,7 @@ CONST
 	NULL = 13; XOR = 14; MULD = 15; ADDC = 16;
 	NULL = 13; XOR = 14; MULD = 15; ADDC = 16;
 	PACK = 17; UNPK = 18;
 	PACK = 17; UNPK = 18;
 
 
-	UseFPUFlag = "useFPU";
+	UseFPU32Flag = "useFPU32";
 	UseFPU64Flag = "useFPU64";
 	UseFPU64Flag = "useFPU64";
 
 
 TYPE
 TYPE
@@ -620,8 +620,10 @@ TYPE
 				*)
 				*)
 
 
 			| IntermediateCode.conv:
 			| IntermediateCode.conv:
-				IF IsInteger64(irInstruction.op1) & IsFloat(irInstruction.op2) THEN  (* ENTIERH *)
+				IF IsInteger64(irInstruction.op1) & IsFloat(irInstruction.op2) THEN  (* ENTIERH: REAL/LONGREAL --> HUGEINT*)
 					result := FALSE
 					result := FALSE
+				ELSIF IsInteger64(irInstruction.op2) & IsFloat(irInstruction.op1) THEN (* HUGEINT --> REAL / HUGEINT --> LONGREAL *)
+					result := FALSE;
 				ELSE
 				ELSE
 					result := ~IsFloat(irInstruction.op1) & ~IsFloat(irInstruction.op2)
 					result := ~IsFloat(irInstruction.op1) & ~IsFloat(irInstruction.op2)
 									OR backend.useFPU32 & ~IsDoublePrecisionFloat(irInstruction.op1) & ~IsDoublePrecisionFloat(irInstruction.op2)
 									OR backend.useFPU32 & ~IsDoublePrecisionFloat(irInstruction.op1) & ~IsDoublePrecisionFloat(irInstruction.op2)
@@ -668,6 +670,12 @@ TYPE
 			IF irInstruction.op1.mode # IntermediateCode.Undefined THEN
 			IF irInstruction.op1.mode # IntermediateCode.Undefined THEN
 				IF (irInstruction.op1.type.form # irInstruction.op2.type.form) OR (irInstruction.op1.type.sizeInBits # irInstruction.op2.type.sizeInBits) THEN
 				IF (irInstruction.op1.type.form # irInstruction.op2.type.form) OR (irInstruction.op1.type.sizeInBits # irInstruction.op2.type.sizeInBits) THEN
 					AppendType(resultingName, irInstruction.op2.type);
 					AppendType(resultingName, irInstruction.op2.type);
+					(* special case: result returned in FPU register *)
+					IF IsSinglePrecisionFloat(irInstruction.op1) & backend.useFPU32 THEN
+						Strings.Append(resultingName, 'F')
+					ELSIF IsDoublePrecisionFloat(irInstruction.op1) & backend.useFPU64 THEN
+						Strings.Append(resultingName, 'F')
+					END;
 				END
 				END
 			END;
 			END;
 
 
@@ -2963,7 +2971,8 @@ TYPE
 				ELSE
 				ELSE
 					(* to non-complex integer: *)
 					(* to non-complex integer: *)
 					IF IsInteger(irSource) THEN
 					IF IsInteger(irSource) THEN
-						(* integer to non-complex integer: ignore high part of source *)
+						(* integer to non-complex integer *)
+						ASSERT(~IsComplex(irSource));
 						GetPartType(irSource.type, Low, partType);
 						GetPartType(irSource.type, Low, partType);
 						SignOrZeroExtendOperand(source[Low], partType);
 						SignOrZeroExtendOperand(source[Low], partType);
 						MovIfDifferent(destination[Low], source[Low])
 						MovIfDifferent(destination[Low], source[Low])
@@ -3001,6 +3010,7 @@ TYPE
 			ELSIF IsSinglePrecisionFloat(irDestination) THEN
 			ELSIF IsSinglePrecisionFloat(irDestination) THEN
 				(* to single precision float: *)
 				(* to single precision float: *)
 			 	IF IsInteger(irSource) THEN
 			 	IF IsInteger(irSource) THEN
+					ASSERT(~IsComplex(irSource));
 			 		(* integer to single precision float: ignore high part of source *)
 			 		(* integer to single precision float: ignore high part of source *)
 			 		temp := GetFreeRegister(IntermediateCode.FloatType(32));
 			 		temp := GetFreeRegister(IntermediateCode.FloatType(32));
 			 		Emit2(opFMSR, temp, source[Low]);
 			 		Emit2(opFMSR, temp, source[Low]);
@@ -3581,7 +3591,7 @@ TYPE
 
 
 		PROCEDURE DefineOptions(options: Options.Options);
 		PROCEDURE DefineOptions(options: Options.Options);
 		BEGIN
 		BEGIN
-			options.Add(0X, UseFPUFlag, Options.Flag);
+			options.Add(0X, UseFPU32Flag, Options.Flag);
 			options.Add(0X, UseFPU64Flag, Options.Flag);
 			options.Add(0X, UseFPU64Flag, Options.Flag);
 			options.Add(0X, "noInitLocals", Options.Flag);
 			options.Add(0X, "noInitLocals", Options.Flag);
 			DefineOptions^(options);
 			DefineOptions^(options);
@@ -3589,7 +3599,7 @@ TYPE
 
 
 		PROCEDURE GetOptions(options: Options.Options);
 		PROCEDURE GetOptions(options: Options.Options);
 		BEGIN
 		BEGIN
-			IF options.GetFlag(UseFPUFlag) THEN useFPU32 := TRUE END;
+			IF options.GetFlag(UseFPU32Flag) THEN useFPU32 := TRUE END;
 			IF options.GetFlag(UseFPU64Flag) THEN useFPU64 := TRUE; useFPU32 := TRUE END;
 			IF options.GetFlag(UseFPU64Flag) THEN useFPU64 := TRUE; useFPU32 := TRUE END;
 			IF options.GetFlag("noInitLocals") THEN initLocals := FALSE END;
 			IF options.GetFlag("noInitLocals") THEN initLocals := FALSE END;
 			GetOptions^(options);
 			GetOptions^(options);