Implement register allocator for floating point registers.

Also:
- Fix misuses of emitting the rex prefix in the x86_64 assembler.
- Fix movaps code generation in the x86_64 assembler.

Change-Id: Ib6dcf6e7c4a9c43368cfc46b02ba50f69ae69cbe
diff --git a/test/410-floats/src/Main.java b/test/410-floats/src/Main.java
index d8d6fac..2300457 100644
--- a/test/410-floats/src/Main.java
+++ b/test/410-floats/src/Main.java
@@ -17,9 +17,10 @@
 public class Main {
   public static void main(String[] args) {
     assertEquals(4.2f, returnFloat());
-    float[] a = new float[1];
+    float[] a = new float[2];
     a[0] = 42.2f;
-    assertEquals(42.2f, returnFloat(a));
+    a[1] = 3.2f;
+    assertEquals(45.4f, returnFloat(a));
 
     assertEquals(4.4, returnDouble());
     double[] b = new double[1];
@@ -36,6 +37,9 @@
     assertEquals(3.1, invokeTakeADouble(3.1));
     assertEquals(12.7, invokeTakeThreeDouble(3.1, 4.4, 5.2));
     assertEquals(12.7f, invokeTakeThreeFloat(3.1f, 4.4f, 5.2f));
+
+    testArrayOperations(new float[2], 0, 1.2f, 3.4f);
+    testArrayOperations(new double[2], 0, 4.1, 7.6);
   }
 
   public static float invokeReturnFloat() {
@@ -51,7 +55,7 @@
   }
 
   public static float returnFloat(float[] a) {
-    return a[0];
+    return a[0] + a[1];
   }
 
   public static double returnDouble() {
@@ -94,6 +98,34 @@
     return takeThreeFloat(a, b, c);
   }
 
+  // Test simple operations on a float array to ensure the register allocator works
+  // properly.
+  public static void testArrayOperations(float[] a, int index, float value1, float value2) {
+    a[0] = value1;
+    a[1] = value2;
+    assertEquals(value1 + value2, a[0] + a[1]);
+    a[0] = 0.0f;
+    a[1] = 0.0f;
+    assertEquals(0.0f, a[0] + a[1]);
+    a[index] = value1;
+    a[index + 1] = value2;
+    assertEquals(value1 + value2, a[0] + a[1]);
+  }
+
+  // Test simple operations on a double array to ensure the register allocator works
+  // properly.
+  public static void testArrayOperations(double[] a, int index, double value1, double value2) {
+    a[0] = value1;
+    a[1] = value2;
+    assertEquals(value1 + value2, a[0] + a[1]);
+    a[0] = 0.0;
+    a[1] = 0.0;
+    assertEquals(0.0, a[0] + a[1]);
+    a[index] = value1;
+    a[index + 1] = value2;
+    assertEquals(value1 + value2, a[0] + a[1]);
+  }
+
   public static void assertEquals(float expected, float actual) {
     if (expected != actual) {
       throw new AssertionError("Expected " + expected + " got " + actual);