Add support for float-to-long in the optimizing compiler.
- Add support for the float-to-long Dex instruction in the
optimizing compiler.
- Add a Dex PC field to art::HTypeConversion to allow the
x86 and ARM code generators to produce runtime calls.
- Instruct art::CodeGenerator::RecordPcInfo not to record
PC information for HTypeConversion instructions.
- Add S0 to the list of ARM FPU parameter registers.
- Have art::x86_64::X86_64Assembler::cvttss2si work with
64-bit operands.
- Generate x86, x86-64 and ARM (but not ARM64) code for
float to long HTypeConversion nodes.
- Add related tests to test/422-type-conversion.
Change-Id: I954214f0d537187883f83f7a83a1bb2dd8a21fd4
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 47fd304..7eecac1 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1394,6 +1394,12 @@
break;
case Primitive::kPrimFloat:
+ // Processing a Dex `float-to-long' instruction.
+ locations->SetInAt(0, Location::RequiresFpuRegister());
+ locations->SetOut(Location::RequiresRegister());
+ locations->AddTemp(Location::RequiresFpuRegister());
+ break;
+
case Primitive::kPrimDouble:
LOG(FATAL) << "Type conversion from " << input_type << " to "
<< result_type << " not yet implemented";
@@ -1565,14 +1571,14 @@
__ movl(output, Immediate(kPrimIntMax));
// temp = int-to-float(output)
- __ cvtsi2ss(temp, output);
+ __ cvtsi2ss(temp, output, false);
// if input >= temp goto done
__ comiss(input, temp);
__ j(kAboveEqual, &done);
// if input == NaN goto nan
__ j(kUnordered, &nan);
// output = float-to-int-truncate(input)
- __ cvttss2si(output, input);
+ __ cvttss2si(output, input, false);
__ jmp(&done);
__ Bind(&nan);
// output = 0
@@ -1604,7 +1610,31 @@
__ movsxd(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>());
break;
- case Primitive::kPrimFloat:
+ case Primitive::kPrimFloat: {
+ // Processing a Dex `float-to-long' instruction.
+ XmmRegister input = in.AsFpuRegister<XmmRegister>();
+ CpuRegister output = out.AsRegister<CpuRegister>();
+ XmmRegister temp = locations->GetTemp(0).AsFpuRegister<XmmRegister>();
+ Label done, nan;
+
+ __ movq(output, Immediate(kPrimLongMax));
+ // temp = int-to-float(output)
+ __ cvtsi2ss(temp, output, true);
+ // if input >= temp goto done
+ __ comiss(input, temp);
+ __ j(kAboveEqual, &done);
+ // if input == NaN goto nan
+ __ j(kUnordered, &nan);
+ // output = float-to-int-truncate(input)
+ __ cvttss2si(output, input, true);
+ __ jmp(&done);
+ __ Bind(&nan);
+ // output = 0
+ __ xorq(output, output);
+ __ Bind(&done);
+ break;
+ }
+
case Primitive::kPrimDouble:
LOG(FATAL) << "Type conversion from " << input_type << " to "
<< result_type << " not yet implemented";