changeset 9425:3ec29630cfb4

Use register categories instead of register flags.
author Roland Schatz <roland.schatz@oracle.com>
date Tue, 30 Apr 2013 12:13:21 +0200
parents 45e1ea931e9c
children 0f8683ac4009
files graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterConfig.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java
diffstat 18 files changed, 313 insertions(+), 279 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java	Tue Apr 30 12:13:21 2013 +0200
@@ -23,12 +23,12 @@
 package com.oracle.graal.amd64;
 
 import static com.oracle.graal.api.code.MemoryBarriers.*;
-import static com.oracle.graal.api.code.Register.RegisterFlag.*;
+import static com.oracle.graal.api.code.Register.*;
 
 import java.nio.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.Register.RegisterFlag;
+import com.oracle.graal.api.code.Register.RegisterCategory;
 import com.oracle.graal.api.meta.*;
 
 /**
@@ -36,26 +36,29 @@
  */
 public class AMD64 extends Architecture {
 
+    public static final RegisterCategory CPU = new RegisterCategory("CPU");
+    public static final RegisterCategory XMM = new RegisterCategory("XMM");
+
     // @formatter:off
 
     // General purpose CPU registers
-    public static final Register rax = new Register(0, 0, 8, "rax", CPU, RegisterFlag.Byte);
-    public static final Register rcx = new Register(1, 1, 8, "rcx", CPU, RegisterFlag.Byte);
-    public static final Register rdx = new Register(2, 2, 8, "rdx", CPU, RegisterFlag.Byte);
-    public static final Register rbx = new Register(3, 3, 8, "rbx", CPU, RegisterFlag.Byte);
-    public static final Register rsp = new Register(4, 4, 8, "rsp", CPU, RegisterFlag.Byte);
-    public static final Register rbp = new Register(5, 5, 8, "rbp", CPU, RegisterFlag.Byte);
-    public static final Register rsi = new Register(6, 6, 8, "rsi", CPU, RegisterFlag.Byte);
-    public static final Register rdi = new Register(7, 7, 8, "rdi", CPU, RegisterFlag.Byte);
+    public static final Register rax = new Register(0, 0, 8, "rax", CPU);
+    public static final Register rcx = new Register(1, 1, 8, "rcx", CPU);
+    public static final Register rdx = new Register(2, 2, 8, "rdx", CPU);
+    public static final Register rbx = new Register(3, 3, 8, "rbx", CPU);
+    public static final Register rsp = new Register(4, 4, 8, "rsp", CPU);
+    public static final Register rbp = new Register(5, 5, 8, "rbp", CPU);
+    public static final Register rsi = new Register(6, 6, 8, "rsi", CPU);
+    public static final Register rdi = new Register(7, 7, 8, "rdi", CPU);
 
-    public static final Register r8  = new Register(8,  8,  8, "r8", CPU, RegisterFlag.Byte);
-    public static final Register r9  = new Register(9,  9,  8, "r9", CPU, RegisterFlag.Byte);
-    public static final Register r10 = new Register(10, 10, 8, "r10", CPU, RegisterFlag.Byte);
-    public static final Register r11 = new Register(11, 11, 8, "r11", CPU, RegisterFlag.Byte);
-    public static final Register r12 = new Register(12, 12, 8, "r12", CPU, RegisterFlag.Byte);
-    public static final Register r13 = new Register(13, 13, 8, "r13", CPU, RegisterFlag.Byte);
-    public static final Register r14 = new Register(14, 14, 8, "r14", CPU, RegisterFlag.Byte);
-    public static final Register r15 = new Register(15, 15, 8, "r15", CPU, RegisterFlag.Byte);
+    public static final Register r8  = new Register(8,  8,  8, "r8", CPU);
+    public static final Register r9  = new Register(9,  9,  8, "r9", CPU);
+    public static final Register r10 = new Register(10, 10, 8, "r10", CPU);
+    public static final Register r11 = new Register(11, 11, 8, "r11", CPU);
+    public static final Register r12 = new Register(12, 12, 8, "r12", CPU);
+    public static final Register r13 = new Register(13, 13, 8, "r13", CPU);
+    public static final Register r14 = new Register(14, 14, 8, "r14", CPU);
+    public static final Register r15 = new Register(15, 15, 8, "r15", CPU);
 
     public static final Register[] cpuRegisters = {
         rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
@@ -63,23 +66,23 @@
     };
 
     // XMM registers
-    public static final Register xmm0 = new Register(16, 0, 8, "xmm0", FPU);
-    public static final Register xmm1 = new Register(17, 1, 8, "xmm1", FPU);
-    public static final Register xmm2 = new Register(18, 2, 8, "xmm2", FPU);
-    public static final Register xmm3 = new Register(19, 3, 8, "xmm3", FPU);
-    public static final Register xmm4 = new Register(20, 4, 8, "xmm4", FPU);
-    public static final Register xmm5 = new Register(21, 5, 8, "xmm5", FPU);
-    public static final Register xmm6 = new Register(22, 6, 8, "xmm6", FPU);
-    public static final Register xmm7 = new Register(23, 7, 8, "xmm7", FPU);
+    public static final Register xmm0 = new Register(16, 0, 8, "xmm0", XMM);
+    public static final Register xmm1 = new Register(17, 1, 8, "xmm1", XMM);
+    public static final Register xmm2 = new Register(18, 2, 8, "xmm2", XMM);
+    public static final Register xmm3 = new Register(19, 3, 8, "xmm3", XMM);
+    public static final Register xmm4 = new Register(20, 4, 8, "xmm4", XMM);
+    public static final Register xmm5 = new Register(21, 5, 8, "xmm5", XMM);
+    public static final Register xmm6 = new Register(22, 6, 8, "xmm6", XMM);
+    public static final Register xmm7 = new Register(23, 7, 8, "xmm7", XMM);
 
-    public static final Register xmm8 =  new Register(24,  8, 8, "xmm8",  FPU);
-    public static final Register xmm9 =  new Register(25,  9, 8, "xmm9",  FPU);
-    public static final Register xmm10 = new Register(26, 10, 8, "xmm10", FPU);
-    public static final Register xmm11 = new Register(27, 11, 8, "xmm11", FPU);
-    public static final Register xmm12 = new Register(28, 12, 8, "xmm12", FPU);
-    public static final Register xmm13 = new Register(29, 13, 8, "xmm13", FPU);
-    public static final Register xmm14 = new Register(30, 14, 8, "xmm14", FPU);
-    public static final Register xmm15 = new Register(31, 15, 8, "xmm15", FPU);
+    public static final Register xmm8 =  new Register(24,  8, 8, "xmm8",  XMM);
+    public static final Register xmm9 =  new Register(25,  9, 8, "xmm9",  XMM);
+    public static final Register xmm10 = new Register(26, 10, 8, "xmm10", XMM);
+    public static final Register xmm11 = new Register(27, 11, 8, "xmm11", XMM);
+    public static final Register xmm12 = new Register(28, 12, 8, "xmm12", XMM);
+    public static final Register xmm13 = new Register(29, 13, 8, "xmm13", XMM);
+    public static final Register xmm14 = new Register(30, 14, 8, "xmm14", XMM);
+    public static final Register xmm15 = new Register(31, 15, 8, "xmm15", XMM);
 
     public static final Register[] xmmRegisters = {
         xmm0, xmm1, xmm2,  xmm3,  xmm4,  xmm5,  xmm6,  xmm7,
@@ -96,7 +99,7 @@
     /**
      * Register used to construct an instruction-relative address.
      */
-    public static final Register rip = new Register(32, -1, 0, "rip");
+    public static final Register rip = new Register(32, -1, 0, "rip", SPECIAL);
 
     public static final Register[] allRegisters = {
         rax,  rcx,  rdx,   rbx,   rsp,   rbp,   rsi,   rdi,
@@ -179,4 +182,44 @@
     public int getSupportedAVXVersion() {
         return supportedAVXVersion;
     }
+
+    @Override
+    public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
+        if (!(platformKind instanceof Kind)) {
+            return false;
+        }
+
+        Kind kind = (Kind) platformKind;
+        if (category == CPU) {
+            switch (kind) {
+                case Boolean:
+                case Byte:
+                case Char:
+                case Short:
+                case Int:
+                case Long:
+                case Object:
+                    return true;
+            }
+        } else if (category == XMM) {
+            switch (kind) {
+                case Float:
+                case Double:
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public PlatformKind getLargestStorableKind(RegisterCategory category) {
+        if (category == CPU) {
+            return Kind.Long;
+        } else if (category == XMM) {
+            return Kind.Double;
+        } else {
+            return Kind.Illegal;
+        }
+    }
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java	Tue Apr 30 12:13:21 2013 +0200
@@ -24,6 +24,7 @@
 
 import java.nio.*;
 
+import com.oracle.graal.api.code.Register.RegisterCategory;
 import com.oracle.graal.api.meta.*;
 
 /**
@@ -196,4 +197,8 @@
                 return 0;
         }
     }
+
+    public abstract boolean canStoreValue(RegisterCategory category, PlatformKind kind);
+
+    public abstract PlatformKind getLargestStorableKind(RegisterCategory category);
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Register.java	Tue Apr 30 12:13:21 2013 +0200
@@ -34,18 +34,20 @@
 
     private static final long serialVersionUID = -7213269157816016300L;
 
+    public static final RegisterCategory SPECIAL = new RegisterCategory("SPECIAL");
+
     /**
      * Invalid register.
      */
-    public static final Register None = new Register(-1, -1, 0, "noreg");
+    public static final Register None = new Register(-1, -1, 0, "noreg", SPECIAL);
 
     /**
      * Frame pointer of the current method. All spill slots and outgoing stack-based arguments are
      * addressed relative to this register.
      */
-    public static final Register Frame = new Register(-2, -2, 0, "framereg", RegisterFlag.CPU);
+    public static final Register Frame = new Register(-2, -2, 0, "framereg", SPECIAL);
 
-    public static final Register CallerFrame = new Register(-3, -3, 0, "callerframereg", RegisterFlag.CPU);
+    public static final Register CallerFrame = new Register(-3, -3, 0, "callerframereg", SPECIAL);
 
     /**
      * The identifier for this register that is unique across all the registers in a
@@ -77,9 +79,10 @@
     public final int spillSlotSize;
 
     /**
-     * The set of {@link RegisterFlag} values associated with this register.
+     * A platform specific register category that describes which values can be stored in a
+     * register.
      */
-    private final int flags;
+    private final RegisterCategory registerCategory;
 
     /**
      * An array of {@link RegisterValue} objects, for this register, with one entry per {@link Kind}
@@ -88,26 +91,20 @@
     private final HashMap<PlatformKind, RegisterValue> values;
 
     /**
-     * Attributes that characterize a register in a useful way.
-     * 
+     * A platform specific register type that describes which values can be stored in a register.
      */
-    public enum RegisterFlag {
-        /**
-         * Denotes an integral (i.e. non floating point) register.
-         */
-        CPU,
+    public static class RegisterCategory {
+
+        private String name;
 
-        /**
-         * Denotes a register whose lowest order byte can be addressed separately.
-         */
-        Byte,
+        public RegisterCategory(String name) {
+            this.name = name;
+        }
 
-        /**
-         * Denotes a floating point register.
-         */
-        FPU;
-
-        public final int mask = 1 << (ordinal() + 1);
+        @Override
+        public String toString() {
+            return name;
+        }
     }
 
     /**
@@ -117,27 +114,19 @@
      * @param encoding the target machine encoding for the register
      * @param spillSlotSize the size of the stack slot used to spill the value of the register
      * @param name the mnemonic name for the register
-     * @param flags the set of {@link RegisterFlag} values for the register
+     * @param registerCategory the register category
      */
-    public Register(int number, int encoding, int spillSlotSize, String name, RegisterFlag... flags) {
+    public Register(int number, int encoding, int spillSlotSize, String name, RegisterCategory registerCategory) {
         this.number = number;
         this.name = name;
         this.spillSlotSize = spillSlotSize;
-        this.flags = createMask(flags);
+        this.registerCategory = registerCategory;
         this.encoding = encoding;
         this.values = new HashMap<>();
     }
 
-    private static int createMask(RegisterFlag... flags) {
-        int result = 0;
-        for (RegisterFlag f : flags) {
-            result |= f.mask;
-        }
-        return result;
-    }
-
-    public boolean isSet(RegisterFlag f) {
-        return (flags & f.mask) != 0;
+    public RegisterCategory getRegisterCategory() {
+        return registerCategory;
     }
 
     /**
@@ -175,29 +164,6 @@
     }
 
     /**
-     * Determines if this a floating point register.
-     */
-    public boolean isFpu() {
-        return isSet(RegisterFlag.FPU);
-    }
-
-    /**
-     * Determines if this a general purpose register.
-     */
-    public boolean isCpu() {
-        return isSet(RegisterFlag.CPU);
-    }
-
-    /**
-     * Determines if this register has the {@link RegisterFlag#Byte} attribute set.
-     * 
-     * @return {@code true} iff this register has the {@link RegisterFlag#Byte} attribute set.
-     */
-    public boolean isByte() {
-        return isSet(RegisterFlag.Byte);
-    }
-
-    /**
      * Gets a hash code for this register.
      * 
      * @return the value of {@link #number}
@@ -208,27 +174,6 @@
     }
 
     /**
-     * Categorizes a set of registers by {@link RegisterFlag}.
-     * 
-     * @param registers a list of registers to be categorized
-     * @return a map from each {@link RegisterFlag} constant to the list of registers for which the
-     *         flag is {@linkplain #isSet(RegisterFlag) set}
-     */
-    public static EnumMap<RegisterFlag, Register[]> categorize(Register[] registers) {
-        EnumMap<RegisterFlag, Register[]> result = new EnumMap<>(RegisterFlag.class);
-        for (RegisterFlag flag : RegisterFlag.values()) {
-            ArrayList<Register> list = new ArrayList<>();
-            for (Register r : registers) {
-                if (r.isSet(flag)) {
-                    list.add(r);
-                }
-            }
-            result.put(flag, list.toArray(new Register[list.size()]));
-        }
-        return result;
-    }
-
-    /**
      * Gets the maximum register {@linkplain #number number} in a given set of registers.
      * 
      * @param registers the set of registers to process
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterConfig.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RegisterConfig.java	Tue Apr 30 12:13:21 2013 +0200
@@ -22,10 +22,7 @@
  */
 package com.oracle.graal.api.code;
 
-import java.util.*;
-
-import com.oracle.graal.api.code.CallingConvention.*;
-import com.oracle.graal.api.code.Register.*;
+import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
 
 /**
@@ -60,12 +57,11 @@
      * given calling convention.
      * 
      * @param type the type of calling convention
-     * @param flag specifies whether registers for {@linkplain RegisterFlag#CPU integral} or
-     *            {@linkplain RegisterFlag#FPU floating point} parameters are being requested
+     * @param kind specifies what kind of registers is being requested
      * @return the ordered set of registers that may be used to pass parameters in a call conforming
      *         to {@code type}
      */
-    Register[] getCallingConventionRegisters(Type type, RegisterFlag flag);
+    Register[] getCallingConventionRegisters(Type type, Kind kind);
 
     /**
      * Gets the set of registers that can be used by the register allocator.
@@ -73,16 +69,10 @@
     Register[] getAllocatableRegisters();
 
     /**
-     * Gets the set of registers that can be used by the register allocator,
-     * {@linkplain Register#categorize(Register[]) categorized} by register
-     * {@linkplain RegisterFlag flags}.
-     * 
-     * @return a map from each {@link RegisterFlag} constant to the list of
-     *         {@linkplain #getAllocatableRegisters() allocatable} registers for which the flag is
-     *         set
-     * 
+     * Gets the set of registers that can be used by the register allocator for a value of a
+     * particular kind.
      */
-    EnumMap<RegisterFlag, Register[]> getCategorizedAllocatableRegisters();
+    Register[] getAllocatableRegisters(PlatformKind kind);
 
     /**
      * Gets the registers whose values must be preserved by a method across any call it makes.
@@ -102,7 +92,6 @@
      * 
      * @return an array where an element at index i holds the attributes of the register whose
      *         number is i
-     * @see Register#categorize(Register[])
      */
     RegisterAttributes[] getAttributesMap();
 
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Tue Apr 30 12:13:21 2013 +0200
@@ -380,7 +380,7 @@
     }
 
     public final void addsd(Register dst, Register src) {
-        assert dst.isFpu() && src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM && src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -389,7 +389,7 @@
     }
 
     public final void addsd(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         prefix(src, dst);
         emitByte(0x0F);
@@ -398,7 +398,7 @@
     }
 
     public final void addss(Register dst, Register src) {
-        assert dst.isFpu() && src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM && src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -407,7 +407,7 @@
     }
 
     public final void addss(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         prefix(src, dst);
         emitByte(0x0F);
@@ -540,7 +540,7 @@
     }
 
     public final void cvtsd2ss(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         prefix(src, dst);
         emitByte(0x0F);
@@ -549,8 +549,8 @@
     }
 
     public final void cvtsd2ss(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -559,7 +559,7 @@
     }
 
     public final void cvtsi2sdl(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         prefix(src, dst);
         emitByte(0x0F);
@@ -568,7 +568,7 @@
     }
 
     public final void cvtsi2sdl(Register dst, Register src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -577,7 +577,7 @@
     }
 
     public final void cvtsi2ssl(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         prefix(src, dst);
         emitByte(0x0F);
@@ -586,7 +586,7 @@
     }
 
     public final void cvtsi2ssl(Register dst, Register src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -595,7 +595,7 @@
     }
 
     public final void cvtss2sd(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         prefix(src, dst);
         emitByte(0x0F);
@@ -604,8 +604,8 @@
     }
 
     public final void cvtss2sd(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -622,7 +622,7 @@
     }
 
     public final void cvttsd2sil(Register dst, Register src) {
-        assert src.isFpu();
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -639,7 +639,7 @@
     }
 
     public final void cvttss2sil(Register dst, Register src) {
-        assert src.isFpu();
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -654,7 +654,7 @@
     }
 
     public final void divsd(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         prefix(src, dst);
         emitByte(0x0F);
@@ -663,8 +663,8 @@
     }
 
     public final void divsd(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -673,7 +673,7 @@
     }
 
     public final void divss(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         prefix(src, dst);
         emitByte(0x0F);
@@ -682,8 +682,8 @@
     }
 
     public final void divss(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -862,8 +862,8 @@
     }
 
     public final void movapd(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         int dstenc = dst.encoding;
         int srcenc = src.encoding;
         emitByte(0x66);
@@ -887,8 +887,8 @@
     }
 
     public final void movaps(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         int dstenc = dst.encoding;
         int srcenc = src.encoding;
         if (dstenc < 8) {
@@ -918,22 +918,22 @@
     }
 
     public final void movb(AMD64Address dst, Register src) {
-        assert src.isByte() : "must have byte register";
+        assert src.getRegisterCategory() == AMD64.CPU : "must have byte register";
         prefix(dst, src); // , true)
         emitByte(0x88);
         emitOperandHelper(src, dst);
     }
 
     public final void movdl(Register dst, Register src) {
-        if (dst.isFpu()) {
-            assert !src.isFpu() : "does this hold?";
+        if (dst.getRegisterCategory() == AMD64.XMM) {
+            assert src.getRegisterCategory() != AMD64.XMM : "does this hold?";
             emitByte(0x66);
             int encode = prefixAndEncode(dst.encoding, src.encoding);
             emitByte(0x0F);
             emitByte(0x6E);
             emitByte(0xC0 | encode);
-        } else if (src.isFpu()) {
-            assert !dst.isFpu();
+        } else if (src.getRegisterCategory() == AMD64.XMM) {
+            assert dst.getRegisterCategory() != AMD64.XMM;
             emitByte(0x66);
             // swap src/dst to get correct prefix
             int encode = prefixAndEncode(src.encoding, dst.encoding);
@@ -981,7 +981,7 @@
      * {@link AMD64MacroAssembler#movflt(Register, Register)}.
      */
     public final void movlpd(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0x66);
         prefix(src, dst);
         emitByte(0x0F);
@@ -990,7 +990,7 @@
     }
 
     public final void movq(Register dst, AMD64Address src) {
-        if (dst.isFpu()) {
+        if (dst.getRegisterCategory() == AMD64.XMM) {
             emitByte(0xF3);
             prefixq(src, dst);
             emitByte(0x0F);
@@ -1010,7 +1010,7 @@
     }
 
     public final void movq(AMD64Address dst, Register src) {
-        if (src.isFpu()) {
+        if (src.getRegisterCategory() == AMD64.XMM) {
             emitByte(0x66);
             prefixq(dst, src);
             emitByte(0x0F);
@@ -1038,8 +1038,8 @@
     }
 
     public final void movsd(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -1048,7 +1048,7 @@
     }
 
     public final void movsd(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         prefix(src, dst);
         emitByte(0x0F);
@@ -1057,7 +1057,7 @@
     }
 
     public final void movsd(AMD64Address dst, Register src) {
-        assert src.isFpu();
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         prefix(dst, src);
         emitByte(0x0F);
@@ -1066,8 +1066,8 @@
     }
 
     public final void movss(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -1076,7 +1076,7 @@
     }
 
     public final void movss(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         prefix(src, dst);
         emitByte(0x0F);
@@ -1085,7 +1085,7 @@
     }
 
     public final void movss(AMD64Address dst, Register src) {
-        assert src.isFpu();
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         prefix(dst, src);
         emitByte(0x0F);
@@ -1137,7 +1137,7 @@
     }
 
     public final void mulsd(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         prefix(src, dst);
         emitByte(0x0F);
@@ -1146,8 +1146,8 @@
     }
 
     public final void mulsd(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
 
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
@@ -1157,7 +1157,7 @@
     }
 
     public final void mulss(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
 
         emitByte(0xF3);
         prefix(src, dst);
@@ -1167,8 +1167,8 @@
     }
 
     public final void mulss(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -1512,8 +1512,8 @@
     }
 
     public final void sqrtsd(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         // HMM Table D-1 says sse2
         // assert is64 || target.supportsSSE();
         emitByte(0xF2);
@@ -1545,8 +1545,8 @@
     }
 
     public final void subsd(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -1555,7 +1555,7 @@
     }
 
     public final void subsd(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
 
         emitByte(0xF2);
         prefix(src, dst);
@@ -1565,8 +1565,8 @@
     }
 
     public final void subss(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -1575,7 +1575,7 @@
     }
 
     public final void subss(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
 
         emitByte(0xF3);
         prefix(src, dst);
@@ -1611,20 +1611,20 @@
     }
 
     public final void ucomisd(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0x66);
         ucomiss(dst, src);
     }
 
     public final void ucomisd(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0x66);
         ucomiss(dst, src);
     }
 
     public final void ucomiss(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
 
         prefix(src, dst);
         emitByte(0x0F);
@@ -1633,8 +1633,8 @@
     }
 
     public final void ucomiss(Register dst, Register src) {
-        assert dst.isFpu();
-        assert src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
+        assert src.getRegisterCategory() == AMD64.XMM;
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0x2E);
@@ -1668,7 +1668,7 @@
     }
 
     public final void andps(Register dst, Register src) {
-        assert dst.isFpu() && src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM && src.getRegisterCategory() == AMD64.XMM;
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0x54);
@@ -1676,7 +1676,7 @@
     }
 
     public final void andps(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         prefix(src, dst);
         emitByte(0x0F);
         emitByte(0x54);
@@ -1694,7 +1694,7 @@
     }
 
     public final void orps(Register dst, Register src) {
-        assert dst.isFpu() && src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM && src.getRegisterCategory() == AMD64.XMM;
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0x56);
@@ -1702,7 +1702,7 @@
     }
 
     public final void orps(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         prefix(src, dst);
         emitByte(0x0F);
         emitByte(0x56);
@@ -1720,7 +1720,7 @@
     }
 
     public final void xorps(Register dst, Register src) {
-        assert dst.isFpu() && src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM && src.getRegisterCategory() == AMD64.XMM;
         int encode = prefixAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
         emitByte(0x57);
@@ -1728,7 +1728,7 @@
     }
 
     public final void xorps(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         prefix(src, dst);
         emitByte(0x0F);
         emitByte(0x57);
@@ -2014,7 +2014,7 @@
     }
 
     public final void cvtsi2sdq(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         prefixq(src, dst);
         emitByte(0x0F);
@@ -2023,7 +2023,7 @@
     }
 
     public final void cvtsi2sdq(Register dst, Register src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -2032,7 +2032,7 @@
     }
 
     public final void cvtsi2ssq(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         prefixq(src, dst);
         emitByte(0x0F);
@@ -2041,7 +2041,7 @@
     }
 
     public final void cvtsi2ssq(Register dst, Register src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -2058,7 +2058,7 @@
     }
 
     public final void cvttsd2siq(Register dst, Register src) {
-        assert src.isFpu();
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF2);
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -2075,7 +2075,7 @@
     }
 
     public final void cvttss2siq(Register dst, Register src) {
-        assert src.isFpu();
+        assert src.getRegisterCategory() == AMD64.XMM;
         emitByte(0xF3);
         int encode = prefixqAndEncode(dst.encoding, src.encoding);
         emitByte(0x0F);
@@ -2154,13 +2154,12 @@
         // table D-1 says MMX/SSE2
         emitByte(0x66);
 
-        if (dst.isFpu()) {
-            assert dst.isFpu();
+        if (dst.getRegisterCategory() == AMD64.XMM) {
             int encode = prefixqAndEncode(dst.encoding, src.encoding);
             emitByte(0x0F);
             emitByte(0x6E);
             emitByte(0xC0 | encode);
-        } else if (src.isFpu()) {
+        } else if (src.getRegisterCategory() == AMD64.XMM) {
 
             // swap src/dst to get correct prefix
             int encode = prefixqAndEncode(src.encoding, dst.encoding);
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Tue Apr 30 12:13:21 2013 +0200
@@ -171,7 +171,7 @@
     }
 
     public final void movflt(Register dst, Register src) {
-        assert dst.isFpu() && src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM && src.getRegisterCategory() == AMD64.XMM;
         if (UseXmmRegToRegMoveAll) {
             movaps(dst, src);
         } else {
@@ -180,17 +180,17 @@
     }
 
     public final void movflt(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         movss(dst, src);
     }
 
     public final void movflt(AMD64Address dst, Register src) {
-        assert src.isFpu();
+        assert src.getRegisterCategory() == AMD64.XMM;
         movss(dst, src);
     }
 
     public final void movdbl(Register dst, Register src) {
-        assert dst.isFpu() && src.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM && src.getRegisterCategory() == AMD64.XMM;
         if (UseXmmRegToRegMoveAll) {
             movapd(dst, src);
         } else {
@@ -199,7 +199,7 @@
     }
 
     public final void movdbl(Register dst, AMD64Address src) {
-        assert dst.isFpu();
+        assert dst.getRegisterCategory() == AMD64.XMM;
         if (UseXmmLoadAndClearUpper) {
             movsd(dst, src);
         } else {
@@ -218,7 +218,7 @@
     }
 
     public final void flog(Register dest, Register value, boolean base10) {
-        assert dest.isFpu() && value.isFpu();
+        assert dest.getRegisterCategory() == AMD64.XMM && value.getRegisterCategory() == AMD64.XMM;
 
         AMD64Address tmp = new AMD64Address(AMD64.rsp);
         if (base10) {
@@ -253,7 +253,7 @@
     }
 
     private AMD64Address trigPrologue(Register value) {
-        assert value.isFpu();
+        assert value.getRegisterCategory() == AMD64.XMM;
         AMD64Address tmp = new AMD64Address(AMD64.rsp);
         subq(AMD64.rsp, 8);
         movsd(tmp, value);
@@ -262,7 +262,7 @@
     }
 
     private void trigEpilogue(Register dest, AMD64Address tmp) {
-        assert dest.isFpu();
+        assert dest.getRegisterCategory() == AMD64.XMM;
         fstp(tmp);
         movsd(dest, tmp);
         addq(AMD64.rsp, 8);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Tue Apr 30 12:13:21 2013 +0200
@@ -305,7 +305,7 @@
             intervals = Arrays.copyOf(intervals, intervals.length * 2);
         }
         intervalsSize++;
-        Variable variable = new Variable(source.kind(), ir.nextVariable(), asVariable(source.operand).flag);
+        Variable variable = new Variable(source.kind(), ir.nextVariable());
         assert variables.size() == variable.index;
         variables.add(variable);
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Tue Apr 30 12:13:21 2013 +0200
@@ -29,7 +29,6 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.Register.RegisterFlag;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.alloc.Interval.RegisterBinding;
 import com.oracle.graal.compiler.alloc.Interval.RegisterPriority;
@@ -811,8 +810,7 @@
     }
 
     void initVarsForAlloc(Interval interval) {
-        EnumMap<RegisterFlag, Register[]> categorizedRegs = allocator.frameMap.registerConfig.getCategorizedAllocatableRegisters();
-        availableRegs = categorizedRegs.get(asVariable(interval.operand).flag);
+        availableRegs = allocator.frameMap.registerConfig.getAllocatableRegisters(interval.kind());
     }
 
     static boolean isMove(LIRInstruction op, Interval from, Interval to) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Apr 30 12:13:21 2013 +0200
@@ -147,22 +147,13 @@
      */
     @Override
     public Variable newVariable(PlatformKind platformKind) {
+        PlatformKind stackKind;
         if (platformKind instanceof Kind) {
-            Kind stackKind = ((Kind) platformKind).getStackKind();
-            switch (stackKind) {
-                case Int:
-                case Long:
-                case Object:
-                    return new Variable(stackKind, lir.nextVariable(), Register.RegisterFlag.CPU);
-                case Float:
-                case Double:
-                    return new Variable(stackKind, lir.nextVariable(), Register.RegisterFlag.FPU);
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
+            stackKind = ((Kind) platformKind).getStackKind();
         } else {
-            return new Variable(platformKind, lir.nextVariable(), Register.RegisterFlag.FPU);
+            stackKind = platformKind;
         }
+        return new Variable(stackKind, lir.nextVariable());
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Tue Apr 30 12:13:21 2013 +0200
@@ -30,7 +30,6 @@
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.Register.RegisterFlag;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.asm.amd64.*;
@@ -71,7 +70,7 @@
 
             @Override
             public void generateCode(AMD64Assembler asm) {
-                Register arg = getArgumentRegister(0, RegisterFlag.CPU);
+                Register arg = getArgumentRegister(0, Kind.Int);
                 asm.addl(arg, 5);
                 asm.movl(rax, arg);
                 asm.ret(0);
@@ -89,7 +88,7 @@
 
             @Override
             public void generateCode(AMD64Assembler asm) {
-                Register arg = getArgumentRegister(0, RegisterFlag.CPU);
+                Register arg = getArgumentRegister(0, Kind.Long);
                 asm.addq(arg, 1);
                 asm.movq(rax, arg);
                 asm.ret(0);
@@ -117,8 +116,8 @@
         Assert.assertArrayEquals(expectedCode, actualCode);
     }
 
-    private Register getArgumentRegister(int index, RegisterFlag flag) {
-        Register[] regs = runtime.lookupRegisterConfig().getCallingConventionRegisters(CallingConvention.Type.JavaCall, flag);
+    private Register getArgumentRegister(int index, Kind kind) {
+        Register[] regs = runtime.lookupRegisterConfig().getCallingConventionRegisters(CallingConvention.Type.JavaCall, kind);
         return regs[index];
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEpilogueOp.java	Tue Apr 30 12:13:21 2013 +0200
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
@@ -39,7 +38,7 @@
      * initial LIR generation is finished. Until then, we use a placeholder variable so that LIR
      * verification is successful.
      */
-    private static final Variable PLACEHOLDER = new Variable(Kind.Long, Integer.MAX_VALUE, Register.RegisterFlag.CPU);
+    private static final Variable PLACEHOLDER = new Variable(Kind.Long, Integer.MAX_VALUE);
 
     @Use({REG, STACK}) protected AllocatableValue savedRbp = PLACEHOLDER;
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Tue Apr 30 12:13:21 2013 +0200
@@ -199,7 +199,9 @@
             Register[] savedRegisters = frameMap.registerConfig.getAllocatableRegisters();
             savedRegisterLocations = new StackSlot[savedRegisters.length];
             for (int i = 0; i < savedRegisters.length; i++) {
-                StackSlot spillSlot = frameMap.allocateSpillSlot(Kind.Long);
+                PlatformKind kind = target.arch.getLargestStorableKind(savedRegisters[i].getRegisterCategory());
+                assert kind != Kind.Illegal;
+                StackSlot spillSlot = frameMap.allocateSpillSlot(kind);
                 savedRegisterLocations[i] = spillSlot;
             }
             save = new AMD64SaveRegistersOp(savedRegisters, savedRegisterLocations);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Tue Apr 30 12:13:21 2013 +0200
@@ -29,7 +29,6 @@
 import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
-import com.oracle.graal.api.code.Register.RegisterFlag;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
@@ -38,9 +37,11 @@
 // @formatter:off
 public class AMD64HotSpotRegisterConfig implements RegisterConfig {
 
+    private final Architecture architecture;
+
     private final Register[] allocatable = initAllocatable();
 
-    private final EnumMap<RegisterFlag, Register[]> categorized = Register.categorize(allocatable);
+    private final HashMap<PlatformKind, Register[]> categorized = new HashMap<>();
 
     private final RegisterAttributes[] attributesMap;
 
@@ -49,9 +50,21 @@
         return allocatable.clone();
     }
 
-    @Override
-    public EnumMap<RegisterFlag, Register[]> getCategorizedAllocatableRegisters() {
-        return categorized.clone();
+    public Register[] getAllocatableRegisters(PlatformKind kind) {
+        if (categorized.containsKey(kind)) {
+            return categorized.get(kind);
+        }
+
+        ArrayList<Register> list = new ArrayList<>();
+        for (Register reg : getAllocatableRegisters()) {
+            if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
+                list.add(reg);
+            }
+        }
+
+        Register[] ret = list.toArray(new Register[0]);
+        categorized.put(kind, ret);
+        return ret;
     }
 
     @Override
@@ -93,7 +106,9 @@
         return allocatable;
     }
 
-    public AMD64HotSpotRegisterConfig(HotSpotVMConfig config, boolean globalStubConfig) {
+    public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, boolean globalStubConfig) {
+        this.architecture = architecture;
+
         if (config.windowsOs) {
             javaGeneralParameterRegisters = new Register[] {rdx, r8, r9, rdi, rsi, rcx};
             nativeGeneralParameterRegisters = new Register[] {rcx, rdx, r8, r9};
@@ -135,10 +150,11 @@
         return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
     }
 
-    public Register[] getCallingConventionRegisters(Type type, RegisterFlag flag) {
-        if (flag == RegisterFlag.FPU) {
+    public Register[] getCallingConventionRegisters(Type type, Kind kind) {
+        if (architecture.canStoreValue(XMM, kind)) {
             return xmmParameterRegisters;
         }
+        assert architecture.canStoreValue(CPU, kind);
         return type == Type.NativeCall ? nativeGeneralParameterRegisters : javaGeneralParameterRegisters;
     }
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Tue Apr 30 12:13:21 2013 +0200
@@ -193,6 +193,6 @@
 
     @Override
     protected RegisterConfig createRegisterConfig(boolean globalStubConfig) {
-        return new AMD64HotSpotRegisterConfig(config, globalStubConfig);
+        return new AMD64HotSpotRegisterConfig(graalRuntime.getTarget().arch, config, globalStubConfig);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Apr 30 12:13:21 2013 +0200
@@ -25,7 +25,6 @@
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
 import static com.oracle.graal.api.code.DeoptimizationAction.*;
 import static com.oracle.graal.api.code.MemoryBarriers.*;
-import static com.oracle.graal.api.code.Register.RegisterFlag.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.api.meta.Value.*;
 import static com.oracle.graal.graph.UnsafeAccess.*;
@@ -56,7 +55,6 @@
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.code.CompilationResult.Mark;
-import com.oracle.graal.api.code.Register.RegisterFlag;
 import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
@@ -192,8 +190,7 @@
         int currentStackOffset = 0;
         for (int i = 0; i < arguments.length; i++) {
             Kind kind = arguments[i];
-            RegisterFlag flag = kind == Kind.Float || kind == Kind.Double ? FPU : CPU;
-            Register[] ccRegs = globalStubRegConfig.getCallingConventionRegisters(type, flag);
+            Register[] ccRegs = globalStubRegConfig.getCallingConventionRegisters(type, kind);
             if (i < ccRegs.length) {
                 result[i] = ccRegs[i].asValue(kind);
             } else {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java	Tue Apr 30 12:13:21 2013 +0200
@@ -39,21 +39,15 @@
     public final int index;
 
     /**
-     * The type of register that this variable needs to get assigned.
-     */
-    public final Register.RegisterFlag flag;
-
-    /**
      * Creates a new variable.
      * 
      * @param kind
      * @param index
      */
-    public Variable(PlatformKind kind, int index, Register.RegisterFlag flag) {
+    public Variable(PlatformKind kind, int index) {
         super(kind);
         assert index >= 0;
         this.index = index;
-        this.flag = flag;
     }
 
     @Override
--- a/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.ptx/src/com/oracle/graal/ptx/PTX.java	Tue Apr 30 12:13:21 2013 +0200
@@ -23,18 +23,21 @@
 package com.oracle.graal.ptx;
 
 import static com.oracle.graal.api.code.MemoryBarriers.*;
-import static com.oracle.graal.api.code.Register.RegisterFlag.*;
 
 import java.nio.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.Register.*;
+import com.oracle.graal.api.code.Register.RegisterCategory;
+import com.oracle.graal.api.meta.*;
 
 /**
  * Represents the PTX architecture.
  */
 public class PTX extends Architecture {
 
+    public static final RegisterCategory CPU = new RegisterCategory("CPU");
+    public static final RegisterCategory FPU = new RegisterCategory("FPU");
+
     // @formatter:off
 
     /*
@@ -49,23 +52,23 @@
      */
 
     // General purpose registers
-    public static final Register r0  = new Register(0,  0,  8, "r0",  CPU, RegisterFlag.Byte);
-    public static final Register r1  = new Register(1,  1,  8, "r1",  CPU, RegisterFlag.Byte);
-    public static final Register r2  = new Register(2,  2,  8, "r2",  CPU, RegisterFlag.Byte);
-    public static final Register r3  = new Register(3,  3,  8, "r3",  CPU, RegisterFlag.Byte);
-    public static final Register r4  = new Register(4,  4,  8, "r4",  CPU, RegisterFlag.Byte);
-    public static final Register r5  = new Register(5,  5,  8, "r5",  CPU, RegisterFlag.Byte);
-    public static final Register r6  = new Register(6,  6,  8, "r6",  CPU, RegisterFlag.Byte);
-    public static final Register r7  = new Register(7,  7,  8, "r7",  CPU, RegisterFlag.Byte);
+    public static final Register r0  = new Register(0,  0,  8, "r0",  CPU);
+    public static final Register r1  = new Register(1,  1,  8, "r1",  CPU);
+    public static final Register r2  = new Register(2,  2,  8, "r2",  CPU);
+    public static final Register r3  = new Register(3,  3,  8, "r3",  CPU);
+    public static final Register r4  = new Register(4,  4,  8, "r4",  CPU);
+    public static final Register r5  = new Register(5,  5,  8, "r5",  CPU);
+    public static final Register r6  = new Register(6,  6,  8, "r6",  CPU);
+    public static final Register r7  = new Register(7,  7,  8, "r7",  CPU);
 
-    public static final Register r8  = new Register(8,  8,  8, "r8",  CPU, RegisterFlag.Byte);
-    public static final Register r9  = new Register(9,  9,  8, "r9",  CPU, RegisterFlag.Byte);
-    public static final Register r10 = new Register(10, 10, 8, "r10", CPU, RegisterFlag.Byte);
-    public static final Register r11 = new Register(11, 11, 8, "r11", CPU, RegisterFlag.Byte);
-    public static final Register r12 = new Register(12, 12, 8, "r12", CPU, RegisterFlag.Byte);
-    public static final Register r13 = new Register(13, 13, 8, "r13", CPU, RegisterFlag.Byte);
-    public static final Register r14 = new Register(14, 14, 8, "r14", CPU, RegisterFlag.Byte);
-    public static final Register r15 = new Register(15, 15, 8, "r15", CPU, RegisterFlag.Byte);
+    public static final Register r8  = new Register(8,  8,  8, "r8",  CPU);
+    public static final Register r9  = new Register(9,  9,  8, "r9",  CPU);
+    public static final Register r10 = new Register(10, 10, 8, "r10", CPU);
+    public static final Register r11 = new Register(11, 11, 8, "r11", CPU);
+    public static final Register r12 = new Register(12, 12, 8, "r12", CPU);
+    public static final Register r13 = new Register(13, 13, 8, "r13", CPU);
+    public static final Register r14 = new Register(14, 14, 8, "r14", CPU);
+    public static final Register r15 = new Register(15, 15, 8, "r15", CPU);
 
     public static final Register[] gprRegisters = {
         r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
@@ -116,4 +119,44 @@
               8);
     }
     // @formatter:on
+
+    @Override
+    public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
+        if (!(platformKind instanceof Kind)) {
+            return false;
+        }
+
+        Kind kind = (Kind) platformKind;
+        if (category == CPU) {
+            switch (kind) {
+                case Boolean:
+                case Byte:
+                case Char:
+                case Short:
+                case Int:
+                case Long:
+                case Object:
+                    return true;
+            }
+        } else if (category == FPU) {
+            switch (kind) {
+                case Float:
+                case Double:
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public PlatformKind getLargestStorableKind(RegisterCategory category) {
+        if (category == CPU) {
+            return Kind.Long;
+        } else if (category == FPU) {
+            return Kind.Double;
+        } else {
+            return Kind.Illegal;
+        }
+    }
 }
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Tue Apr 30 12:05:50 2013 +0200
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Tue Apr 30 12:13:21 2013 +0200
@@ -27,6 +27,8 @@
 import java.nio.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.Register.RegisterCategory;
+import com.oracle.graal.api.meta.*;
 
 /**
  * Represents the SPARC architecture.
@@ -39,4 +41,16 @@
         super("AMD64", 8, ByteOrder.LITTLE_ENDIAN, null, LOAD_STORE | STORE_STORE, 1, 0, 8);
         // SPARC: Fix architecture parameters.
     }
+
+    @Override
+    public boolean canStoreValue(RegisterCategory category, PlatformKind kind) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public PlatformKind getLargestStorableKind(RegisterCategory category) {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }