changeset 20149:b1a8928fc4b9

[SPARC] Implement new instructions in assembler/enhance assertion error-message in MoveResolver
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Thu, 02 Apr 2015 18:45:28 +0200
parents 921eeb012866
children 7bf5292dd7ad
files graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java
diffstat 5 files changed, 154 insertions(+), 87 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Thu Apr 02 17:32:26 2015 +0200
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Thu Apr 02 18:45:28 2015 +0200
@@ -29,6 +29,7 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.Opfs.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.sparc.SPARC.*;
+import static java.lang.String.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -261,7 +262,9 @@
         Fcmp  (0b11_0101, "fcmp", Op10),
 
         Ldxa  (0b01_1011, "ldxa", Op11),
-        Lduwa (0b01_0000, "lduwa", Op11);
+        Lduwa (0b01_0000, "lduwa", Op11),
+
+        Tcc(0b11_1010, "tcc", Op10);
 
         // @formatter:on
 
@@ -1098,13 +1101,13 @@
     }
 
     private void cbcond(int cc2, int i, ConditionFlag cf, Register rs1, int rs2, Label l) {
-        int d10 = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4;
-        assert isSimm(d10, 10) && isImm(rs2, 5);
-        d10 &= (1 << 10) - 1;
+        int disp10 = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4;
+        assert isSimm(disp10, 10) && isImm(rs2, 5);
+        disp10 &= (1 << 10) - 1;
         final int cLo = cf.value & 0b111;
         final int cHi = cf.value >> 3;
-        final int d10Lo = d10 & ((1 << 8) - 1);
-        final int d10Hi = d10 >> 8;
+        final int d10Lo = disp10 & ((1 << 8) - 1);
+        final int d10Hi = disp10 >> 8;
         int a = cHi << 4 | 0b1000 | cLo;
         int b = cc2 << 21 | d10Hi << D10HI_SHIFT | rs1.encoding << 14 | i << 13 | d10Lo << D10LO_SHIFT | rs2;
         fmt00(a, Op2s.Bpr.value, b);
@@ -1200,6 +1203,7 @@
     }
 
     public void movwtos(Register rs2, Register rd) {
+        assert isSingleFloatRegister(rd) && isCPURegister(rs2) : String.format("%s %s", rs2, rd);
         op3(Impdep1, Movwtos, null, rs2, rd);
     }
 
@@ -1208,22 +1212,27 @@
     }
 
     public void fdtos(Register rs2, Register rd) {
+        assert isSingleFloatRegister(rd) && isDoubleFloatRegister(rs2) : String.format("%s %s", rs2, rd);
         op3(Fpop1, Fdtos, null, rs2, rd);
     }
 
     public void movstouw(Register rs2, Register rd) {
+        assert isSingleFloatRegister(rs2) && isCPURegister(rd) : String.format("%s %s", rs2, rd);
         op3(Impdep1, Movstosw, null, rs2, rd);
     }
 
     public void movstosw(Register rs2, Register rd) {
+        assert isSingleFloatRegister(rs2) && isCPURegister(rd) : String.format("%s %s", rs2, rd);
         op3(Impdep1, Movstosw, null, rs2, rd);
     }
 
     public void movdtox(Register rs2, Register rd) {
+        assert isDoubleFloatRegister(rs2) && isCPURegister(rd) : String.format("%s %s", rs2, rd);
         op3(Impdep1, Movdtox, null, rs2, rd);
     }
 
     public void movxtod(Register rs2, Register rd) {
+        assert isCPURegister(rs2) && isDoubleFloatRegister(rd) : String.format("%s %s", rs2, rd);
         op3(Impdep1, Movxtod, null, rs2, rd);
     }
 
@@ -1456,10 +1465,12 @@
     }
 
     public void or(Register rs1, Register rs2, Register rd) {
+        assert isCPURegister(rs1, rs2, rd) : String.format("%s %s %s", rs1, rs2, rd);
         op3(Or, rs1, rs2, rd);
     }
 
     public void or(Register rs1, int simm13, Register rd) {
+        assert isCPURegister(rs1, rd) : String.format("%s %s", rs1, rd);
         op3(Or, rs1, simm13, rd);
     }
 
@@ -1598,8 +1609,9 @@
     public void tcc(CC cc, ConditionFlag flag, int trap) {
         assert isImm(trap, 8);
         int b = cc.value << 11;
+        b |= 1 << 13;
         b |= trap;
-        fmt10(flag.value, trap, 0, b);
+        fmt10(flag.value, Op3s.Tcc.getValue(), 0, b);
     }
 
     public void wrccr(Register rs1, Register rs2) {
@@ -1659,46 +1671,57 @@
     }
 
     public void lddf(SPARCAddress src, Register dst) {
+        assert isDoubleFloatRegister(dst) : dst;
         ld(Lddf, src, dst);
     }
 
     public void ldf(SPARCAddress src, Register dst) {
+        assert isSingleFloatRegister(dst) : dst;
         ld(Ldf, src, dst);
     }
 
     public void lduh(SPARCAddress src, Register dst) {
+        assert isCPURegister(dst) : dst;
         ld(Lduh, src, dst);
     }
 
     public void ldsh(SPARCAddress src, Register dst) {
+        assert isCPURegister(dst) : dst;
         ld(Ldsh, src, dst);
     }
 
     public void ldub(SPARCAddress src, Register dst) {
+        assert isCPURegister(dst) : dst;
         ld(Ldub, src, dst);
     }
 
     public void ldsb(SPARCAddress src, Register dst) {
+        assert isCPURegister(dst) : dst;
         ld(Ldsb, src, dst);
     }
 
     public void lduw(SPARCAddress src, Register dst) {
+        assert isCPURegister(dst) : dst;
         ld(Lduw, src, dst);
     }
 
     public void ldsw(SPARCAddress src, Register dst) {
+        assert isCPURegister(dst) : dst;
         ld(Ldsw, src, dst);
     }
 
     public void ldx(SPARCAddress src, Register dst) {
+        assert isCPURegister(dst) : dst;
         ld(Ldx, src, dst);
     }
 
     public void ldxa(Register rs1, Register rs2, Register rd, Asi asi) {
+        assert SPARC.isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
         ld(Ldxa, new SPARCAddress(rs1, rs2), rd, asi);
     }
 
     public void lduwa(Register rs1, Register rs2, Register rd, Asi asi) {
+        assert SPARC.isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
         ld(Lduwa, new SPARCAddress(rs1, rs2), rd, asi);
     }
 
@@ -1707,26 +1730,32 @@
     }
 
     public void stdf(Register rd, SPARCAddress addr) {
+        assert isDoubleFloatRegister(rd) : rd;
         st(Stdf, rd, addr);
     }
 
     public void stf(Register rd, SPARCAddress addr) {
+        assert isSingleFloatRegister(rd) : rd;
         st(Stf, rd, addr);
     }
 
     public void stb(Register rd, SPARCAddress addr) {
+        assert isCPURegister(rd) : rd;
         st(Stb, rd, addr);
     }
 
     public void sth(Register rd, SPARCAddress addr) {
+        assert isCPURegister(rd) : rd;
         st(Sth, rd, addr);
     }
 
     public void stw(Register rd, SPARCAddress addr) {
+        assert isCPURegister(rd) : rd;
         st(Stw, rd, addr);
     }
 
     public void stx(Register rd, SPARCAddress addr) {
+        assert isCPURegister(rd) : rd;
         st(Stx, rd, addr);
     }
 
@@ -1757,4 +1786,8 @@
         inst |= simm13 & ((1 << 12) - 1);
         emitInt(inst, position);
     }
+
+    public void fpadd32(Register rs1, Register rs2, Register rd) {
+        op3(Impdep1, Fpadd32, rs1, rs2, rd);
+    }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Thu Apr 02 17:32:26 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Thu Apr 02 18:45:28 2015 +0200
@@ -90,6 +90,7 @@
     private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
 
     private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
+    private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null};
     // @formatter:off
     private final Register[] callerSaveRegisters =
                    {g1, g2, g3, g4, g5, g6, g7,
@@ -208,7 +209,7 @@
     }
 
     public Register[] getCallingConventionRegisters(Type type, Kind kind) {
-        if (architecture.canStoreValue(FPU, kind)) {
+        if (architecture.canStoreValue(FPUs, kind) || architecture.canStoreValue(FPUd, kind)) {
             return fpuParameterRegisters;
         }
         assert architecture.canStoreValue(CPU, kind);
@@ -244,7 +245,7 @@
                             // Make register number even to be a double reg
                             currentFloating++;
                         }
-                        Register register = fpuParameterRegisters[currentFloating];
+                        Register register = fpuDoubleParameterRegisters[currentFloating];
                         currentFloating += 2; // Only every second is a double register
                         locations[i] = register.asValue(target.getLIRKind(kind));
                     }
@@ -289,8 +290,9 @@
             case Object:
                 return type == Type.JavaCallee ? i0 : o0;
             case Float:
+                return f0;
             case Double:
-                return f0;
+                return d0;
             case Void:
             case Illegal:
                 return null;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Thu Apr 02 17:32:26 2015 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Thu Apr 02 18:45:28 2015 +0200
@@ -256,11 +256,11 @@
     public abstract static class MemOp extends SPARCLIRInstruction implements ImplicitNullCheck {
         public static final LIRInstructionClass<MemOp> TYPE = LIRInstructionClass.create(MemOp.class);
 
-        protected final Kind kind;
+        protected final PlatformKind kind;
         @Use({COMPOSITE}) protected SPARCAddressValue address;
         @State protected LIRFrameState state;
 
-        public MemOp(LIRInstructionClass<? extends MemOp> c, Kind kind, SPARCAddressValue address, LIRFrameState state) {
+        public MemOp(LIRInstructionClass<? extends MemOp> c, PlatformKind kind, SPARCAddressValue address, LIRFrameState state) {
             super(c);
             this.kind = kind;
             this.address = address;
@@ -303,7 +303,7 @@
                 if (state != null) {
                     crb.recordImplicitException(masm.position(), state);
                 }
-                switch (kind) {
+                switch ((Kind) kind) {
                     case Boolean:
                     case Byte:
                         masm.ldsb(addr, dst);
@@ -502,7 +502,7 @@
                 if (state != null) {
                     crb.recordImplicitException(masm.position(), state);
                 }
-                switch (kind) {
+                switch ((Kind) kind) {
                     case Boolean:
                     case Byte:
                         masm.stb(asRegister(input), addr);
@@ -555,7 +555,7 @@
                 if (state != null) {
                     crb.recordImplicitException(masm.position(), state);
                 }
-                switch (kind) {
+                switch ((Kind) kind) {
                     case Boolean:
                     case Byte:
                         masm.stb(g0, addr);
@@ -755,16 +755,17 @@
         try (ScratchRegister sc = masm.getScratchRegister()) {
             Register scratch = sc.getRegister();
             boolean hasVIS3 = ((SPARC) masm.target.arch).getFeatures().contains(CPUFeature.VIS3);
+            Register resultRegister = asRegister(result);
             switch (input.getKind().getStackKind()) {
                 case Int:
                     if (input.isDefaultForKind()) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        masm.clr(asIntReg(result));
+                        masm.clr(resultRegister);
                     } else if (isSimm13(input.asLong())) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        masm.or(g0, input.asInt(), asIntReg(result));
+                        masm.or(g0, input.asInt(), resultRegister);
                     } else {
-                        Setx set = new Setx(input.asLong(), asIntReg(result), false, true);
+                        Setx set = new Setx(input.asLong(), resultRegister, false, true);
                         set.emitFirstPartOfDelayed(masm);
                         delaySlotLir.emitControlTransfer(crb, masm);
                         set.emitSecondPartOfDelayed(masm);
@@ -773,12 +774,12 @@
                 case Long:
                     if (input.isDefaultForKind()) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        masm.clr(asLongReg(result));
+                        masm.clr(resultRegister);
                     } else if (isSimm13(input.asLong())) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        masm.or(g0, (int) input.asLong(), asLongReg(result));
+                        masm.or(g0, (int) input.asLong(), resultRegister);
                     } else {
-                        Setx setx = new Setx(input.asLong(), asLongReg(result), false, true);
+                        Setx setx = new Setx(input.asLong(), resultRegister, false, true);
                         setx.emitFirstPartOfDelayed(masm);
                         delaySlotLir.emitControlTransfer(crb, masm);
                         setx.emitSecondPartOfDelayed(masm);
@@ -789,7 +790,7 @@
                     int constantBits = java.lang.Float.floatToIntBits(constant);
                     if (constantBits == 0) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        masm.fzeros(asFloatReg(result));
+                        masm.fzeros(resultRegister);
                     } else {
                         if (hasVIS3) {
                             if (isSimm13(constantBits)) {
@@ -799,24 +800,24 @@
                             }
                             delaySlotLir.emitControlTransfer(crb, masm);
                             // Now load the float value
-                            masm.movwtos(scratch, asFloatReg(result));
+                            masm.movwtos(scratch, resultRegister);
                         } else {
                             crb.asFloatConstRef(input);
                             // First load the address into the scratch register
                             new Setx(0, scratch, true).emit(masm);
                             // Now load the float value
                             delaySlotLir.emitControlTransfer(crb, masm);
-                            masm.ldf(new SPARCAddress(scratch, 0), asFloatReg(result));
+                            masm.ldf(new SPARCAddress(scratch, 0), resultRegister);
                         }
                     }
                     break;
                 }
                 case Double: {
                     double constant = input.asDouble();
-                    long constantBits = java.lang.Double.doubleToLongBits(constant);
+                    long constantBits = java.lang.Double.doubleToRawLongBits(constant);
                     if (constantBits == 0) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        masm.fzerod(asDoubleReg(result));
+                        masm.fzerod(resultRegister);
                     } else {
                         if (hasVIS3) {
                             if (isSimm13(constantBits)) {
@@ -826,14 +827,14 @@
                             }
                             delaySlotLir.emitControlTransfer(crb, masm);
                             // Now load the float value
-                            masm.movxtod(scratch, asDoubleReg(result));
+                            masm.movxtod(scratch, resultRegister);
                         } else {
                             crb.asDoubleConstRef(input);
                             // First load the address into the scratch register
                             new Setx(0, scratch, true).emit(masm);
                             delaySlotLir.emitControlTransfer(crb, masm);
                             // Now load the float value
-                            masm.lddf(new SPARCAddress(scratch, 0), asDoubleReg(result));
+                            masm.lddf(new SPARCAddress(scratch, 0), resultRegister);
                         }
                     }
                     break;
@@ -841,10 +842,10 @@
                 case Object:
                     if (input.isNull()) {
                         delaySlotLir.emitControlTransfer(crb, masm);
-                        masm.clr(asRegister(result));
+                        masm.clr(resultRegister);
                     } else if (crb.target.inlineObjects) {
                         crb.recordInlineDataInCode(input); // relocatable cannot be delayed
-                        new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm);
+                        new Setx(0xDEADDEADDEADDEADL, resultRegister, true).emit(masm);
                     } else {
                         throw GraalInternalError.unimplemented();
                     }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java	Thu Apr 02 17:32:26 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java	Thu Apr 02 18:45:28 2015 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.lir.alloc.lsra;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static java.lang.String.*;
 
 import java.util.*;
 
@@ -209,7 +210,7 @@
     }
 
     private void insertMove(Value fromOpr, Interval toInterval) {
-        assert fromOpr.getLIRKind().equals(toInterval.kind()) : "move between different types";
+        assert fromOpr.getLIRKind().equals(toInterval.kind()) : format("move between different types %s %s", fromOpr.getLIRKind(), toInterval.kind());
         assert insertIdx != -1 : "must setup insert position first";
 
         AllocatableValue toOpr = toInterval.operand;
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Thu Apr 02 17:32:26 2015 +0200
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Thu Apr 02 18:45:28 2015 +0200
@@ -123,62 +123,81 @@
     };
     // @formatter:on
 
-    public static final RegisterCategory FPU = new RegisterCategory("FPU", cpuRegisters.length);
+    public static final RegisterCategory FPUs = new RegisterCategory("FPUs", cpuRegisters.length);
+    public static final RegisterCategory FPUd = new RegisterCategory("FPUd", cpuRegisters.length + 32);
 
     // Floating point registers
-    public static final Register f0 = new Register(32, 0, "f0", FPU);
-    public static final Register f1 = new Register(33, 1, "f1", FPU);
-    public static final Register f2 = new Register(34, 2, "f2", FPU);
-    public static final Register f3 = new Register(35, 3, "f3", FPU);
-    public static final Register f4 = new Register(36, 4, "f4", FPU);
-    public static final Register f5 = new Register(37, 5, "f5", FPU);
-    public static final Register f6 = new Register(38, 6, "f6", FPU);
-    public static final Register f7 = new Register(39, 7, "f7", FPU);
+    public static final Register f0 = new Register(32, 0, "f0", FPUs);
+    public static final Register f1 = new Register(33, 1, "f1", FPUs);
+    public static final Register f2 = new Register(34, 2, "f2", FPUs);
+    public static final Register f3 = new Register(35, 3, "f3", FPUs);
+    public static final Register f4 = new Register(36, 4, "f4", FPUs);
+    public static final Register f5 = new Register(37, 5, "f5", FPUs);
+    public static final Register f6 = new Register(38, 6, "f6", FPUs);
+    public static final Register f7 = new Register(39, 7, "f7", FPUs);
+
+    public static final Register f8 = new Register(40, 8, "f8", FPUs);
+    public static final Register f9 = new Register(41, 9, "f9", FPUs);
+    public static final Register f10 = new Register(42, 10, "f10", FPUs);
+    public static final Register f11 = new Register(43, 11, "f11", FPUs);
+    public static final Register f12 = new Register(44, 12, "f12", FPUs);
+    public static final Register f13 = new Register(45, 13, "f13", FPUs);
+    public static final Register f14 = new Register(46, 14, "f14", FPUs);
+    public static final Register f15 = new Register(47, 15, "f15", FPUs);
 
-    public static final Register f8 = new Register(40, 8, "f8", FPU);
-    public static final Register f9 = new Register(41, 9, "f9", FPU);
-    public static final Register f10 = new Register(42, 10, "f10", FPU);
-    public static final Register f11 = new Register(43, 11, "f11", FPU);
-    public static final Register f12 = new Register(44, 12, "f12", FPU);
-    public static final Register f13 = new Register(45, 13, "f13", FPU);
-    public static final Register f14 = new Register(46, 14, "f14", FPU);
-    public static final Register f15 = new Register(47, 15, "f15", FPU);
+    public static final Register f16 = new Register(48, 16, "f16", FPUs);
+    public static final Register f17 = new Register(49, 17, "f17", FPUs);
+    public static final Register f18 = new Register(50, 18, "f18", FPUs);
+    public static final Register f19 = new Register(51, 19, "f19", FPUs);
+    public static final Register f20 = new Register(52, 20, "f20", FPUs);
+    public static final Register f21 = new Register(53, 21, "f21", FPUs);
+    public static final Register f22 = new Register(54, 22, "f22", FPUs);
+    public static final Register f23 = new Register(55, 23, "f23", FPUs);
 
-    public static final Register f16 = new Register(48, 16, "f16", FPU);
-    public static final Register f17 = new Register(49, 17, "f17", FPU);
-    public static final Register f18 = new Register(50, 18, "f18", FPU);
-    public static final Register f19 = new Register(51, 19, "f19", FPU);
-    public static final Register f20 = new Register(52, 20, "f20", FPU);
-    public static final Register f21 = new Register(53, 21, "f21", FPU);
-    public static final Register f22 = new Register(54, 22, "f22", FPU);
-    public static final Register f23 = new Register(55, 23, "f23", FPU);
+    public static final Register f24 = new Register(56, 24, "f24", FPUs);
+    public static final Register f25 = new Register(57, 25, "f25", FPUs);
+    public static final Register f26 = new Register(58, 26, "f26", FPUs);
+    public static final Register f27 = new Register(59, 27, "f27", FPUs);
+    public static final Register f28 = new Register(60, 28, "f28", FPUs);
+    public static final Register f29 = new Register(61, 29, "f29", FPUs);
+    public static final Register f30 = new Register(62, 30, "f30", FPUs);
+    public static final Register f31 = new Register(63, 31, "f31", FPUs);
 
-    public static final Register f24 = new Register(56, 24, "f24", FPU);
-    public static final Register f25 = new Register(57, 25, "f25", FPU);
-    public static final Register f26 = new Register(58, 26, "f26", FPU);
-    public static final Register f27 = new Register(59, 27, "f27", FPU);
-    public static final Register f28 = new Register(60, 28, "f28", FPU);
-    public static final Register f29 = new Register(61, 29, "f29", FPU);
-    public static final Register f30 = new Register(62, 30, "f30", FPU);
-    public static final Register f31 = new Register(63, 31, "f31", FPU);
+    public static final Register d0 = new Register(32, getDoubleEncoding(0), "d0", FPUs);
+    public static final Register d2 = new Register(34, getDoubleEncoding(2), "d2", FPUs);
+    public static final Register d4 = new Register(36, getDoubleEncoding(4), "d4", FPUs);
+    public static final Register d6 = new Register(38, getDoubleEncoding(6), "d6", FPUs);
+    public static final Register d8 = new Register(40, getDoubleEncoding(8), "d8", FPUs);
+    public static final Register d10 = new Register(42, getDoubleEncoding(10), "d10", FPUs);
+    public static final Register d12 = new Register(44, getDoubleEncoding(12), "d12", FPUs);
+    public static final Register d14 = new Register(46, getDoubleEncoding(14), "d14", FPUs);
+
+    public static final Register d16 = new Register(48, getDoubleEncoding(16), "d16", FPUs);
+    public static final Register d18 = new Register(50, getDoubleEncoding(18), "d18", FPUs);
+    public static final Register d20 = new Register(52, getDoubleEncoding(20), "d20", FPUs);
+    public static final Register d22 = new Register(54, getDoubleEncoding(22), "d22", FPUs);
+    public static final Register d24 = new Register(56, getDoubleEncoding(24), "d24", FPUs);
+    public static final Register d26 = new Register(58, getDoubleEncoding(26), "d26", FPUs);
+    public static final Register d28 = new Register(60, getDoubleEncoding(28), "d28", FPUs);
+    public static final Register d30 = new Register(62, getDoubleEncoding(28), "d28", FPUs);
 
-    public static final Register d32 = new Register(64, getDoubleEncoding(32), "d32", FPU);
-    public static final Register d34 = new Register(65, getDoubleEncoding(34), "d34", FPU);
-    public static final Register d36 = new Register(66, getDoubleEncoding(36), "d36", FPU);
-    public static final Register d38 = new Register(67, getDoubleEncoding(38), "d38", FPU);
-    public static final Register d40 = new Register(68, getDoubleEncoding(40), "d40", FPU);
-    public static final Register d42 = new Register(69, getDoubleEncoding(42), "d42", FPU);
-    public static final Register d44 = new Register(70, getDoubleEncoding(44), "d44", FPU);
-    public static final Register d46 = new Register(71, getDoubleEncoding(46), "d46", FPU);
+    public static final Register d32 = new Register(64, getDoubleEncoding(32), "d32", FPUd);
+    public static final Register d34 = new Register(65, getDoubleEncoding(34), "d34", FPUd);
+    public static final Register d36 = new Register(66, getDoubleEncoding(36), "d36", FPUd);
+    public static final Register d38 = new Register(67, getDoubleEncoding(38), "d38", FPUd);
+    public static final Register d40 = new Register(68, getDoubleEncoding(40), "d40", FPUd);
+    public static final Register d42 = new Register(69, getDoubleEncoding(42), "d42", FPUd);
+    public static final Register d44 = new Register(70, getDoubleEncoding(44), "d44", FPUd);
+    public static final Register d46 = new Register(71, getDoubleEncoding(46), "d46", FPUd);
 
-    public static final Register d48 = new Register(72, getDoubleEncoding(48), "d48", FPU);
-    public static final Register d50 = new Register(73, getDoubleEncoding(50), "d50", FPU);
-    public static final Register d52 = new Register(74, getDoubleEncoding(52), "d52", FPU);
-    public static final Register d54 = new Register(75, getDoubleEncoding(54), "d54", FPU);
-    public static final Register d56 = new Register(76, getDoubleEncoding(56), "d56", FPU);
-    public static final Register d58 = new Register(77, getDoubleEncoding(58), "d58", FPU);
-    public static final Register d60 = new Register(78, getDoubleEncoding(60), "d60", FPU);
-    public static final Register d62 = new Register(79, getDoubleEncoding(62), "d62", FPU);
+    public static final Register d48 = new Register(72, getDoubleEncoding(48), "d48", FPUd);
+    public static final Register d50 = new Register(73, getDoubleEncoding(50), "d50", FPUd);
+    public static final Register d52 = new Register(74, getDoubleEncoding(52), "d52", FPUd);
+    public static final Register d54 = new Register(75, getDoubleEncoding(54), "d54", FPUd);
+    public static final Register d56 = new Register(76, getDoubleEncoding(56), "d56", FPUd);
+    public static final Register d58 = new Register(77, getDoubleEncoding(58), "d58", FPUd);
+    public static final Register d60 = new Register(78, getDoubleEncoding(60), "d60", FPUd);
+    public static final Register d62 = new Register(79, getDoubleEncoding(62), "d62", FPUd);
 
     // @formatter:off
     public static final Register[] fpuRegisters = {
@@ -248,12 +267,10 @@
                 case Object:
                     return true;
             }
-        } else if (category.equals(FPU)) {
-            switch (kind) {
-                case Float:
-                case Double:
-                    return true;
-            }
+        } else if (category.equals(FPUs) && kind.equals(Kind.Float)) {
+            return true;
+        } else if (category.equals(FPUd) && kind.equals(Kind.Double)) {
+            return true;
         }
         return false;
     }
@@ -262,7 +279,7 @@
     public PlatformKind getLargestStorableKind(RegisterCategory category) {
         if (category.equals(CPU)) {
             return Kind.Long;
-        } else if (category.equals(FPU)) {
+        } else if (category.equals(FPUs)) {
             return Kind.Double;
         } else {
             return Kind.Illegal;
@@ -279,6 +296,19 @@
         return (reg & 0x1e) | ((reg & 0x20) >> 5);
     }
 
+    public static boolean isCPURegister(Register r) {
+        return r.getRegisterCategory().equals(CPU);
+    }
+
+    public static boolean isCPURegister(Register... regs) {
+        for (Register reg : regs) {
+            if (!isCPURegister(reg)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     public static boolean isSingleFloatRegister(Register r) {
         return r.name.startsWith("f");
     }