changeset 10686:73122b5edf6a

SPARC: Can compile simple methods and do static calls.
author twisti
date Tue, 09 Jul 2013 15:37:50 -0700
parents 431eca622358
children 87d2df0a7624
files graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java
diffstat 20 files changed, 1034 insertions(+), 493 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAddress.java	Tue Jul 09 15:37:50 2013 -0700
@@ -22,11 +22,17 @@
  */
 package com.oracle.graal.asm.sparc;
 
-import com.oracle.graal.api.code.AbstractAddress;
-import com.oracle.graal.api.code.Register;
+import static com.oracle.graal.sparc.SPARC.*;
+
+import com.oracle.graal.api.code.*;
 
 public class SPARCAddress extends AbstractAddress {
 
+    /**
+     * Stack bias for stack and frame pointer loads.
+     */
+    private static final int STACK_BIAS = 0x7ff;
+
     private final Register base;
     private final int displacement; // need Register offset / displacement CompositeValue?
 
@@ -66,6 +72,10 @@
      * @return Optional additive displacement.
      */
     public int getDisplacement() {
+        // TODO Should we also hide the register save area size here?
+        if (getBase() == sp || getBase() == fp) {
+            return displacement + STACK_BIAS;
+        }
         return displacement;
     }
 }
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java	Tue Jul 09 15:37:50 2013 -0700
@@ -36,7 +36,7 @@
 public abstract class SPARCAssembler extends AbstractAssembler {
 
     /**
-     * Constructs an assembler for the AMD64 architecture.
+     * Constructs an assembler for the SPARC architecture.
      * 
      * @param registerConfig the register configuration used to bind {@link Register#Frame} and
      *            {@link Register#CallerFrame} to physical registers. This value can be null if this
@@ -47,6 +47,14 @@
         super(target);
     }
 
+    // @formatter:off
+    /**
+     * Instruction format for sethi.
+     * 
+     * | 00  |  rd    | op2 |               imm22                     |
+     * |31 30|29    25|24 22|21                                      0|
+     */
+    // @formatter:on
     public static class Fmt00a {
 
         private int rd;
@@ -74,9 +82,9 @@
      * |31 30|29|28  25|24 22|21                                      0|
      */
     // @formatter:on
-    public static class Fmt2b {
-
-        public Fmt2b(SPARCAssembler masm, int op, int a, int cond, int op2, int disp22) {
+    public static class Fmt00b {
+
+        public Fmt00b(SPARCAssembler masm, int op, int a, int cond, int op2, int disp22) {
             assert op == 0;
             assert op == 0;
             assert cond < 0x10;
@@ -211,7 +219,7 @@
             final int op2 = (inst & OP2_MASK) >> OP2_SHIFT;
             final int cc = (inst & CC_MASK) >> CC_SHIFT;
             final int p = (inst & P_MASK) >> P_SHIFT;
-            final int disp19 = (inst & DISP19_MASK) >> DISP19_SHIFT;
+            final int disp19 = (inst & DISP19_MASK) >> DISP19_SHIFT << 2;
 
             Fmt00c fmt = new Fmt00c(a, cond, op2, cc, p, disp19);
             fmt.verify();
@@ -240,9 +248,9 @@
         }
     }
 
-    public static class Fmt2d {
-
-        public Fmt2d(SPARCAssembler masm, int op, int a, int rcond, int op2, int d16hi, int predict, int rs1, int d16lo) {
+    public static class Fmt00d {
+
+        public Fmt00d(SPARCAssembler masm, int op, int a, int rcond, int op2, int d16hi, int predict, int rs1, int d16lo) {
             assert predict == 0 || predict == 1;
             assert rcond >= 0 && rcond < 0x8;
             assert op == 0;
@@ -253,9 +261,9 @@
         }
     }
 
-    public static class Fmt2e {
-
-        public Fmt2e(SPARCAssembler asm, int op, int c4lo, int cc2, int rs1, int d10lo, int regOrImmediate) {
+    public static class Fmt00e {
+
+        public Fmt00e(SPARCAssembler asm, int op, int c4lo, int cc2, int rs1, int d10lo, int regOrImmediate) {
             assert op == 0;
             assert (cc2 & 0xFFFFFFFE) == 0;
             assert c4lo >= 0 && rs1 < 0x10;
@@ -268,110 +276,75 @@
         }
     }
 
+    // @formatter:off
+    /**
+     * Instruction format for calls.
+     * 
+     * | 01  |                      disp30                             |
+     * |31 30|29                                                      0|
+     */
+    // @formatter:on
     public static class Fmt01 {
 
+        private static final int OP_SHIFT = 30;
+        private static final int DISP30_SHIFT = 0;
+
+        // @formatter:off
+        private static final int OP_MASK     = 0b11000000000000000000000000000000;
+        private static final int DISP30_MASK = 0b00111111111111111111111111111111;
+        // @formatter:on
+
         private int disp30;
 
         public Fmt01(int disp30) {
-            this.disp30 = disp30;
-        }
-
-        public void emit(SPARCAssembler masm) {
-            assert ((disp30 & 0xc0000000) == 0);
-            masm.emitInt(Ops.CallOp.getValue() << 30 | disp30);
-        }
-    }
-
-    public static class Fmt3a {
-
-        public Fmt3a(SPARCAssembler masm, int op, int rd, int op3, int rs1, int rs2) {
-            assert op == 2 || op == 3;
-            assert op3 >= 0 && op3 < 0x40;
-            assert rs1 >= 0 && rs1 < 0x20;
-            assert rs2 >= 0 && rs2 < 0x20;
-            assert rd >= 0 && rd < 0x20;
-
-            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | rs2);
-        }
-    }
-
-    public static class Fmt3b {
-
-        private boolean isImm;
-        private int op;
-        private int op3;
-        private int rs1;
-        private int rs2;
-        private int simm13;
-        private int rd;
-
-        public Fmt3b(Ops op, Op3s op3, Register rs1, Register rs2, Register rd) {
-            this.op = op.getValue();
-            this.op3 = op3.getValue();
-            this.rs1 = rs1.encoding();
-            this.rs2 = rs2.encoding();
-            this.rd = rd.encoding();
-        }
-
-        public Fmt3b(Ops op, Op3s op3, Register rs1, int simm13, Register rd) {
-            isImm = true;
-            this.op = op.getValue();
-            this.op3 = op3.getValue();
-            this.rs1 = rs1.encoding();
-            this.simm13 = simm13;
-            this.rd = rd.encoding();
+            setDisp30(disp30);
+        }
+
+        /**
+         * Return the displacement in bytes.
+         */
+        public int getDisp30() {
+            return disp30 << 2;
+        }
+
+        /**
+         * The instructions requires displacements to be word-sized.
+         */
+        public void setDisp30(int disp30) {
+            this.disp30 = disp30 >> 2;
+        }
+
+        private int getInstructionBits() {
+            return Ops.CallOp.getValue() << OP_SHIFT | (disp30 & DISP30_MASK) << DISP30_SHIFT;
+        }
+
+        public static Fmt01 read(SPARCAssembler masm, int pos) {
+            final int inst = masm.codeBuffer.getInt(pos);
+
+            // Make sure it's the right instruction:
+            final int op = (inst & OP_MASK) >> OP_SHIFT;
+            assert op == Ops.CallOp.getValue();
+
+            // Get the instruction fields:
+            final int disp30 = (inst & DISP30_MASK) >> DISP30_SHIFT << 2;
+
+            Fmt01 fmt = new Fmt01(disp30);
+            fmt.verify();
+            return fmt;
+        }
+
+        public void write(SPARCAssembler masm, int pos) {
+            verify();
+            masm.codeBuffer.emitInt(getInstructionBits(), pos);
         }
 
         public void emit(SPARCAssembler masm) {
-            assert op == 2 || op == 3;
-            assert op3 >= 0 && op3 < 0x40;
-            assert rs1 >= 0 && rs1 < 0x20;
-            assert rd >= 0 && rd < 0x20;
-
-            if (isImm == false) {
-                assert rs2 >= 0 && rs2 < 0x20;
-                masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | rs2);
-            } else {
-                assert isSimm13(simm13) : simm13;
-                masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | ImmedTrue | (simm13 & 0x1fff));
-            }
-        }
-    }
-
-    public static class Fmt3c {
-
-        public Fmt3c(SPARCAssembler masm, int op, int op3, int rs1, int rs2) {
-            assert op == 2;
-            assert op3 >= 0 && op3 < 0x40;
-            assert rs1 >= 0 && rs1 < 0x20;
-            assert rs2 >= 0 && rs2 < 0x20;
-
-            masm.emitInt(op << 30 | op3 << 19 | rs1 << 14 | rs2);
-        }
-    }
-
-    public static class Fmt3d {
-
-        public Fmt3d(SPARCAssembler masm, int op, int op3, int rs1, int simm13) {
-            assert op == 2;
-            assert op3 >= 0 && op3 < 0x40;
-            assert rs1 >= 0 && rs1 < 0x20;
-
-            masm.emitInt(op << 30 | op3 << 19 | rs1 << 14 | ImmedTrue | simm13);
-        }
-    }
-
-    public static class Fmt3e {
-
-        public Fmt3e(SPARCAssembler masm, int op, int op3, int rcond, int rs1, int rs2, int rd) {
-            assert op == 2 || op == 3;
-            assert op3 >= 0 && op3 < 0x40;
-            assert rcond >= 0 && rcond < 0x8;
-            assert rs1 >= 0 && rs1 < 0x20;
-            assert rs2 >= 0 && rs2 < 0x20;
-            assert rd >= 0 && rd < 0x20;
-
-            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | rcond << 10 | rs2);
+            verify();
+            masm.emitInt(getInstructionBits());
+        }
+
+        public void verify() {
+            assert (disp30 & DISP30_MASK) == 0;
         }
     }
 
@@ -430,26 +403,227 @@
         }
     }
 
-    public static class Fmt3q {
-
-        public Fmt3q(SPARCAssembler masm, int op, int op3, int rs1, int rd) {
-            assert op == 2 || op == 3;
-            assert op3 >= 0 && op3 < 0x40;
-            assert rs1 >= 0 && rs1 < 0x20;
-            assert rd >= 0 && rd < 0x20;
-
-            masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14);
+    // @formatter:off
+    /**
+     * Instruction format for Arithmetic, Logical, Moves, Tcc, Prefetch, and Misc.
+     * 
+     * | 10  |   rd   |   op3   |   rs1   | i|   imm_asi   |   rs2   |
+     * | 10  |   rd   |   op3   |   rs1   | i|        simm13         |
+     * |31 30|29    25|24     19|18     14|13|12          5|4       0|
+     */
+    // @formatter:on
+    public static class Fmt10 {
+
+        private static final int OP_SHIFT = 30;
+        private static final int RD_SHIFT = 25;
+        private static final int OP3_SHIFT = 19;
+        private static final int RS1_SHIFT = 14;
+        private static final int I_SHIFT = 13;
+        private static final int IMM_ASI_SHIFT = 5;
+        private static final int RS2_SHIFT = 0;
+        private static final int SIMM13_SHIFT = 0;
+
+        // @formatter:off
+        private static final int OP_MASK      = 0b11000000000000000000000000000000;
+        private static final int RD_MASK      = 0b00111110000000000000000000000000;
+        private static final int OP3_MASK     = 0b00000001111110000000000000000000;
+        private static final int RS1_MASK     = 0b00000000000001111100000000000000;
+        private static final int I_MASK       = 0b00000000000000000010000000000000;
+        private static final int IMM_ASI_MASK = 0b00000000000000000001111111100000;
+        private static final int RS2_MASK     = 0b00000000000000000000000000011111;
+        private static final int SIMM13_MASK  = 0b00000000000000000001111111111111;
+        // @formatter:on
+
+        private int rd;
+        private int op3;
+        private int rs1;
+        private int i;
+        private int immAsi;
+        private int rs2;
+        private int simm13;
+
+        private Fmt10(int rd, int op3, int rs1, int i, int immAsi, int rs2, int simm13) {
+            this.rd = rd;
+            this.op3 = op3;
+            this.rs1 = rs1;
+            this.i = i;
+            this.immAsi = immAsi;
+            this.rs2 = rs2;
+            this.simm13 = simm13;
+            verify();
+        }
+
+        public Fmt10(Op3s op3, Register rs1, Register rs2, Register rd) {
+            this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, rs2.encoding(), 0);
+        }
+
+        public Fmt10(Op3s op3, Register rs1, int simm13, Register rd) {
+            this(rd.encoding(), op3.getValue(), rs1.encoding(), 1, 0, 0, simm13);
+        }
+
+        public Fmt10(Op3s op3) {
+            this(0, op3.getValue(), 0, 0, 0, 0, 0);
+        }
+
+        public Fmt10(Op3s op3, Register rs1, Register rd) {
+            this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, 0, 0);
+        }
+
+        private int getInstructionBits() {
+            if (i == 0) {
+                return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | immAsi << IMM_ASI_SHIFT | rs2 << RS2_SHIFT;
+            } else {
+                return Ops.ArithOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | ((simm13 << SIMM13_SHIFT) & SIMM13_MASK);
+            }
+        }
+
+        public static Fmt10 read(SPARCAssembler masm, int pos) {
+            final int inst = masm.codeBuffer.getInt(pos);
+
+            // Make sure it's the right instruction:
+            final int op = (inst & OP_MASK) >> OP_SHIFT;
+            assert op == Ops.ArithOp.getValue();
+
+            // Get the instruction fields:
+            final int rd = (inst & RD_MASK) >> RD_SHIFT;
+            final int op3 = (inst & OP3_MASK) >> OP3_SHIFT;
+            final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT;
+            final int i = (inst & I_MASK) >> I_SHIFT;
+            final int immAsi = (inst & IMM_ASI_MASK) >> IMM_ASI_SHIFT;
+            final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT;
+            final int simm13 = (inst & SIMM13_MASK) >> SIMM13_SHIFT;
+
+            return new Fmt10(rd, op3, rs1, i, immAsi, rs2, simm13);
+        }
+
+        public void write(SPARCAssembler masm, int pos) {
+            verify();
+            masm.codeBuffer.emitInt(getInstructionBits(), pos);
+        }
+
+        public void emit(SPARCAssembler masm) {
+            verify();
+            masm.emitInt(getInstructionBits());
+        }
+
+        public void verify() {
+            assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT);
+            assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT);
+            assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT);
+            assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT);
+            assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT);
+            assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT);
+            assert isSimm13(simm13);
         }
     }
 
-    public static class Fmt3r {
-
-        public Fmt3r(SPARCAssembler masm, int op, int fcn, int op3) {
-            assert op == 23;
-            assert op3 >= 0 && op3 < 0x40;
-            assert fcn >= 0 && fcn < 0x40;
-
-            masm.emitInt(op << 30 | fcn << 25 | op3 << 19);
+    // @formatter:off
+    /**
+     * Instruction format for Loads, Stores and Misc.
+     * 
+     * | 11  |   rd   |   op3   |   rs1   | i|   imm_asi   |   rs2   |
+     * | 11  |   rd   |   op3   |   rs1   | i|        simm13         |
+     * |31 30|29    25|24     19|18     14|13|12          5|4       0|
+     */
+    // @formatter:on
+    public static class Fmt11 {
+
+        private static final int OP_SHIFT = 30;
+        private static final int RD_SHIFT = 25;
+        private static final int OP3_SHIFT = 19;
+        private static final int RS1_SHIFT = 14;
+        private static final int I_SHIFT = 13;
+        private static final int IMM_ASI_SHIFT = 5;
+        private static final int RS2_SHIFT = 0;
+        private static final int SIMM13_SHIFT = 0;
+
+        // @formatter:off
+        private static final int OP_MASK      = 0b11000000000000000000000000000000;
+        private static final int RD_MASK      = 0b00111110000000000000000000000000;
+        private static final int OP3_MASK     = 0b00000001111110000000000000000000;
+        private static final int RS1_MASK     = 0b00000000000001111100000000000000;
+        private static final int I_MASK       = 0b00000000000000000010000000000000;
+        private static final int IMM_ASI_MASK = 0b00000000000000000001111111100000;
+        private static final int RS2_MASK     = 0b00000000000000000000000000011111;
+        private static final int SIMM13_MASK  = 0b00000000000000000001111111111111;
+        // @formatter:on
+
+        private int rd;
+        private int op3;
+        private int rs1;
+        private int i;
+        private int immAsi;
+        private int rs2;
+        private int simm13;
+
+        private Fmt11(int rd, int op3, int rs1, int i, int immAsi, int rs2, int simm13) {
+            this.rd = rd;
+            this.op3 = op3;
+            this.rs1 = rs1;
+            this.i = i;
+            this.immAsi = immAsi;
+            this.rs2 = rs2;
+            this.simm13 = simm13;
+            verify();
+        }
+
+        public Fmt11(Op3s op3, Register rs1, Register rs2, Register rd) {
+            this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, rs2.encoding(), 0);
+        }
+
+        public Fmt11(Op3s op3, Register rs1, int simm13, Register rd) {
+            this(rd.encoding(), op3.getValue(), rs1.encoding(), 1, 0, 0, simm13);
+        }
+
+        public Fmt11(Op3s op3, Register rs1, Register rd) {
+            this(rd.encoding(), op3.getValue(), rs1.encoding(), 0, 0, 0, 0);
+        }
+
+        private int getInstructionBits() {
+            if (i == 0) {
+                return Ops.LdstOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | immAsi << IMM_ASI_SHIFT | rs2 << RS2_SHIFT;
+            } else {
+                return Ops.LdstOp.getValue() << OP_SHIFT | rd << RD_SHIFT | op3 << OP3_SHIFT | rs1 << RS1_SHIFT | i << I_SHIFT | ((simm13 << SIMM13_SHIFT) & SIMM13_MASK);
+            }
+        }
+
+        public static Fmt11 read(SPARCAssembler masm, int pos) {
+            final int inst = masm.codeBuffer.getInt(pos);
+
+            // Make sure it's the right instruction:
+            final int op = (inst & OP_MASK) >> OP_SHIFT;
+            assert op == Ops.LdstOp.getValue();
+
+            // Get the instruction fields:
+            final int rd = (inst & RD_MASK) >> RD_SHIFT;
+            final int op3 = (inst & OP3_MASK) >> OP3_SHIFT;
+            final int rs1 = (inst & RS1_MASK) >> RS1_SHIFT;
+            final int i = (inst & I_MASK) >> I_SHIFT;
+            final int immAsi = (inst & IMM_ASI_MASK) >> IMM_ASI_SHIFT;
+            final int rs2 = (inst & RS2_MASK) >> RS2_SHIFT;
+            final int simm13 = (inst & SIMM13_MASK) >> SIMM13_SHIFT;
+
+            return new Fmt11(rd, op3, rs1, i, immAsi, rs2, simm13);
+        }
+
+        public void write(SPARCAssembler masm, int pos) {
+            verify();
+            masm.codeBuffer.emitInt(getInstructionBits(), pos);
+        }
+
+        public void emit(SPARCAssembler masm) {
+            verify();
+            masm.emitInt(getInstructionBits());
+        }
+
+        public void verify() {
+            assert ((rd << RD_SHIFT) & RD_MASK) == (rd << RD_SHIFT);
+            assert ((op3 << OP3_SHIFT) & OP3_MASK) == (op3 << OP3_SHIFT);
+            assert ((rs1 << RS1_SHIFT) & RS1_MASK) == (rs1 << RS1_SHIFT);
+            assert ((i << I_SHIFT) & I_MASK) == (i << I_SHIFT);
+            assert ((immAsi << IMM_ASI_SHIFT) & IMM_ASI_MASK) == (immAsi << IMM_ASI_SHIFT);
+            assert ((rs2 << RS2_SHIFT) & RS2_MASK) == (rs2 << RS2_SHIFT);
+            assert isSimm13(simm13);
         }
     }
 
@@ -1060,47 +1234,47 @@
         return x & ((1 << 10) - 1);
     }
 
-    public static class Add extends Fmt3b {
+    public static class Add extends Fmt10 {
 
         public Add(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Add, src1, simm13, dst);
+            super(Op3s.Add, src1, simm13, dst);
         }
 
         public Add(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Add, src1, src2, dst);
+            super(Op3s.Add, src1, src2, dst);
         }
     }
 
-    public static class Addc extends Fmt3b {
+    public static class Addc extends Fmt10 {
 
         public Addc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Addc, src1, simm13, dst);
+            super(Op3s.Addc, src1, simm13, dst);
         }
 
         public Addc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Addc, src1, src2, dst);
+            super(Op3s.Addc, src1, src2, dst);
         }
     }
 
-    public static class Addcc extends Fmt3b {
+    public static class Addcc extends Fmt10 {
 
         public Addcc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Addcc, src1, simm13, dst);
+            super(Op3s.Addcc, src1, simm13, dst);
         }
 
         public Addcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Addcc, src1, src2, dst);
+            super(Op3s.Addcc, src1, src2, dst);
         }
     }
 
-    public static class Addccc extends Fmt3b {
+    public static class Addccc extends Fmt10 {
 
         public Addccc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Addccc, src1, simm13, dst);
+            super(Op3s.Addccc, src1, simm13, dst);
         }
 
         public Addccc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Addccc, src1, src2, dst);
+            super(Op3s.Addccc, src1, src2, dst);
         }
     }
 
@@ -1136,47 +1310,47 @@
         }
     }
 
-    public static class And extends Fmt3b {
+    public static class And extends Fmt10 {
 
         public And(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.And, src1, simm13, dst);
+            super(Op3s.And, src1, simm13, dst);
         }
 
         public And(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.And, src1, src2, dst);
+            super(Op3s.And, src1, src2, dst);
         }
     }
 
-    public static class Andcc extends Fmt3b {
+    public static class Andcc extends Fmt10 {
 
         public Andcc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Andcc, src1, simm13, dst);
+            super(Op3s.Andcc, src1, simm13, dst);
         }
 
         public Andcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Andcc, src1, src2, dst);
+            super(Op3s.Andcc, src1, src2, dst);
         }
     }
 
-    public static class Andn extends Fmt3b {
+    public static class Andn extends Fmt10 {
 
         public Andn(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Andn, src1, simm13, dst);
+            super(Op3s.Andn, src1, simm13, dst);
         }
 
         public Andn(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Andn, src1, src2, dst);
+            super(Op3s.Andn, src1, src2, dst);
         }
     }
 
-    public static class Andncc extends Fmt3b {
+    public static class Andncc extends Fmt10 {
 
         public Andncc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Andncc, src1, simm13, dst);
+            super(Op3s.Andncc, src1, simm13, dst);
         }
 
         public Andncc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Andncc, src1, src2, dst);
+            super(Op3s.Andncc, src1, src2, dst);
         }
     }
 
@@ -1396,6 +1570,13 @@
         }
     }
 
+    public static class Call extends Fmt01 {
+
+        public Call(int disp30) {
+            super(disp30);
+        }
+    }
+
     public static class CammelliaFl extends Fmt3p {
 
         public CammelliaFl(Register src1, Register src2, Register dst) {
@@ -1446,7 +1627,7 @@
         }
     }
 
-    public static class Cwbcc extends Fmt2e {
+    public static class Cwbcc extends Fmt00e {
 
         public Cwbcc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1457,7 +1638,7 @@
         }
     }
 
-    public static class Cwbcs extends Fmt2e {
+    public static class Cwbcs extends Fmt00e {
 
         public Cwbcs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1468,7 +1649,7 @@
         }
     }
 
-    public static class Cwbe extends Fmt2e {
+    public static class Cwbe extends Fmt00e {
 
         public Cwbe(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1479,7 +1660,7 @@
         }
     }
 
-    public static class Cwbg extends Fmt2e {
+    public static class Cwbg extends Fmt00e {
 
         public Cwbg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1490,7 +1671,7 @@
         }
     }
 
-    public static class Cwbge extends Fmt2e {
+    public static class Cwbge extends Fmt00e {
 
         public Cwbge(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1501,7 +1682,7 @@
         }
     }
 
-    public static class Cwbgu extends Fmt2e {
+    public static class Cwbgu extends Fmt00e {
 
         public Cwbgu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1512,7 +1693,7 @@
         }
     }
 
-    public static class Cwbl extends Fmt2e {
+    public static class Cwbl extends Fmt00e {
 
         public Cwbl(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1523,7 +1704,7 @@
         }
     }
 
-    public static class Cwble extends Fmt2e {
+    public static class Cwble extends Fmt00e {
 
         public Cwble(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1534,7 +1715,7 @@
         }
     }
 
-    public static class Cwbleu extends Fmt2e {
+    public static class Cwbleu extends Fmt00e {
 
         public Cwbleu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1545,7 +1726,7 @@
         }
     }
 
-    public static class Cwbne extends Fmt2e {
+    public static class Cwbne extends Fmt00e {
 
         public Cwbne(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1556,7 +1737,7 @@
         }
     }
 
-    public static class Cwbneg extends Fmt2e {
+    public static class Cwbneg extends Fmt00e {
 
         public Cwbneg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1567,7 +1748,7 @@
         }
     }
 
-    public static class Cwbpos extends Fmt2e {
+    public static class Cwbpos extends Fmt00e {
 
         public Cwbpos(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1578,7 +1759,7 @@
         }
     }
 
-    public static class Cwbvc extends Fmt2e {
+    public static class Cwbvc extends Fmt00e {
 
         public Cwbvc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1589,7 +1770,7 @@
         }
     }
 
-    public static class Cwbvs extends Fmt2e {
+    public static class Cwbvs extends Fmt00e {
 
         public Cwbvs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 0, src1.encoding(), simm10, src2.encoding());
@@ -1600,7 +1781,7 @@
         }
     }
 
-    public static class Cxbcc extends Fmt2e {
+    public static class Cxbcc extends Fmt00e {
 
         public Cxbcc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1611,7 +1792,7 @@
         }
     }
 
-    public static class Cxbcs extends Fmt2e {
+    public static class Cxbcs extends Fmt00e {
 
         public Cxbcs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarrySet.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1622,7 +1803,7 @@
         }
     }
 
-    public static class Cxbe extends Fmt2e {
+    public static class Cxbe extends Fmt00e {
 
         public Cxbe(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.CarryClear.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1633,7 +1814,7 @@
         }
     }
 
-    public static class Cxbg extends Fmt2e {
+    public static class Cxbg extends Fmt00e {
 
         public Cxbg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.Greater.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1644,7 +1825,7 @@
         }
     }
 
-    public static class Cxbge extends Fmt2e {
+    public static class Cxbge extends Fmt00e {
 
         public Cxbge(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterEqual.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1655,7 +1836,7 @@
         }
     }
 
-    public static class Cxbgu extends Fmt2e {
+    public static class Cxbgu extends Fmt00e {
 
         public Cxbgu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.GreaterUnsigned.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1666,7 +1847,7 @@
         }
     }
 
-    public static class Cxbl extends Fmt2e {
+    public static class Cxbl extends Fmt00e {
 
         public Cxbl(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.Less.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1677,7 +1858,7 @@
         }
     }
 
-    public static class Cxble extends Fmt2e {
+    public static class Cxble extends Fmt00e {
 
         public Cxble(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqual.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1688,7 +1869,7 @@
         }
     }
 
-    public static class Cxbleu extends Fmt2e {
+    public static class Cxbleu extends Fmt00e {
 
         public Cxbleu(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.LessEqualUnsigned.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1699,7 +1880,7 @@
         }
     }
 
-    public static class Cxbne extends Fmt2e {
+    public static class Cxbne extends Fmt00e {
 
         public Cxbne(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.NotEqual.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1710,7 +1891,7 @@
         }
     }
 
-    public static class Cxbneg extends Fmt2e {
+    public static class Cxbneg extends Fmt00e {
 
         public Cxbneg(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.Negative.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1721,7 +1902,7 @@
         }
     }
 
-    public static class Cxbpos extends Fmt2e {
+    public static class Cxbpos extends Fmt00e {
 
         public Cxbpos(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.Positive.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1732,7 +1913,7 @@
         }
     }
 
-    public static class Cxbvc extends Fmt2e {
+    public static class Cxbvc extends Fmt00e {
 
         public Cxbvc(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowClear.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -1743,7 +1924,7 @@
         }
     }
 
-    public static class Cxbvs extends Fmt2e {
+    public static class Cxbvs extends Fmt00e {
 
         public Cxbvs(SPARCAssembler asm, Register src1, Register src2, int simm10) {
             super(asm, Ops.BranchOp.getValue(), ConditionFlag.OverflowSet.getValue(), 1, src1.encoding(), simm10, src2.encoding());
@@ -2098,10 +2279,10 @@
         }
     }
 
-    public static class Flushw extends Fmt3r {
-
-        public Flushw(SPARCAssembler masm) {
-            super(masm, Ops.ArithOp.getValue(), 0, Op3s.Flushw.getValue());
+    public static class Flushw extends Fmt10 {
+
+        public Flushw() {
+            super(Op3s.Flushw);
         }
     }
 
@@ -2296,67 +2477,67 @@
         }
     }
 
-    public static class Jmpl extends Fmt3b {
+    public static class Jmpl extends Fmt10 {
 
         public Jmpl(Register src, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Jmpl, src, simm13, dst);
+            super(Op3s.Jmpl, src, simm13, dst);
         }
     }
 
-    public static class Lddf extends Fmt3b {
+    public static class Lddf extends Fmt11 {
 
         // TODO remove address
         public Lddf(SPARCAddress src, Register dst) {
-            super(Ops.LdstOp, Op3s.Lddf, src.getBase(), src.getDisplacement(), dst);
+            super(Op3s.Lddf, src.getBase(), src.getDisplacement(), dst);
         }
     }
 
-    public static class Ldf extends Fmt3b {
+    public static class Ldf extends Fmt11 {
 
         public Ldf(SPARCAddress src, Register dst) {
-            super(Ops.LdstOp, Op3s.Ldf, src.getBase(), src.getDisplacement(), dst);
+            super(Op3s.Ldf, src.getBase(), src.getDisplacement(), dst);
         }
     }
 
-    public static class Ldsb extends Fmt3b {
+    public static class Ldsb extends Fmt11 {
 
         public Ldsb(SPARCAddress src, Register dst) {
-            super(Ops.LdstOp, Op3s.Ldsb, src.getBase(), src.getDisplacement(), dst);
+            super(Op3s.Ldsb, src.getBase(), src.getDisplacement(), dst);
         }
     }
 
-    public static class Ldsh extends Fmt3b {
+    public static class Ldsh extends Fmt11 {
 
         public Ldsh(SPARCAddress src, Register dst) {
-            super(Ops.LdstOp, Op3s.Ldsh, src.getBase(), src.getDisplacement(), dst);
+            super(Op3s.Ldsh, src.getBase(), src.getDisplacement(), dst);
         }
     }
 
-    public static class Ldsw extends Fmt3b {
+    public static class Ldsw extends Fmt11 {
 
         public Ldsw(SPARCAddress src, Register dst) {
-            super(Ops.LdstOp, Op3s.Ldsw, src.getBase(), src.getDisplacement(), dst);
+            super(Op3s.Ldsw, src.getBase(), src.getDisplacement(), dst);
         }
     }
 
-    public static class Lduw extends Fmt3b {
+    public static class Lduw extends Fmt11 {
 
         public Lduw(SPARCAddress src, Register dst) {
-            super(Ops.LdstOp, Op3s.Lduw, src.getBase(), src.getDisplacement(), dst);
+            super(Op3s.Lduw, src.getBase(), src.getDisplacement(), dst);
         }
     }
 
-    public static class Ldx extends Fmt3b {
+    public static class Ldx extends Fmt11 {
 
         public Ldx(SPARCAddress src, Register dst) {
-            super(Ops.LdstOp, Op3s.Ldx, src.getBase(), src.getDisplacement(), dst);
+            super(Op3s.Ldx, src.getBase(), src.getDisplacement(), dst);
         }
     }
 
-    public static class Membar extends Fmt3b {
+    public static class Membar extends Fmt10 {
 
         public Membar(int barriers) {
-            super(Ops.ArithOp, Op3s.Membar, r15, ImmedTrue | barriers, r0);
+            super(Op3s.Membar, r15, barriers, r0);
         }
     }
 
@@ -2383,209 +2564,209 @@
     }
 
     @Deprecated
-    public static class Mulscc extends Fmt3b {
+    public static class Mulscc extends Fmt10 {
 
         @Deprecated
         public Mulscc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Mulscc, src1, simm13, dst);
+            super(Op3s.Mulscc, src1, simm13, dst);
         }
 
         @Deprecated
         public Mulscc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Mulscc, src1, src2, dst);
+            super(Op3s.Mulscc, src1, src2, dst);
         }
     }
 
-    public static class Mulx extends Fmt3b {
+    public static class Mulx extends Fmt10 {
 
         public Mulx(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Mulx, src1, simm13, dst);
+            super(Op3s.Mulx, src1, simm13, dst);
         }
 
         public Mulx(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Mulx, src1, src2, dst);
+            super(Op3s.Mulx, src1, src2, dst);
         }
     }
 
-    public static class Or extends Fmt3b {
+    public static class Or extends Fmt10 {
 
         public Or(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Or, src1, simm13, dst);
+            super(Op3s.Or, src1, simm13, dst);
         }
 
         public Or(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Or, src1, src2, dst);
+            super(Op3s.Or, src1, src2, dst);
         }
     }
 
-    public static class Orcc extends Fmt3b {
+    public static class Orcc extends Fmt10 {
 
         public Orcc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Orcc, src1, simm13, dst);
+            super(Op3s.Orcc, src1, simm13, dst);
         }
 
         public Orcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Orcc, src1, src2, dst);
+            super(Op3s.Orcc, src1, src2, dst);
         }
     }
 
-    public static class Orn extends Fmt3b {
+    public static class Orn extends Fmt10 {
 
         public Orn(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Orn, src1, simm13, dst);
+            super(Op3s.Orn, src1, simm13, dst);
         }
 
         public Orn(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Orn, src1, src2, dst);
+            super(Op3s.Orn, src1, src2, dst);
         }
     }
 
-    public static class Orncc extends Fmt3b {
+    public static class Orncc extends Fmt10 {
 
         public Orncc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Orncc, src1, simm13, dst);
+            super(Op3s.Orncc, src1, simm13, dst);
         }
 
         public Orncc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Orncc, src1, src2, dst);
+            super(Op3s.Orncc, src1, src2, dst);
         }
     }
 
-    public static class Popc extends Fmt3b {
+    public static class Popc extends Fmt10 {
 
         public Popc(int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Popc, r0, simm13, dst);
+            super(Op3s.Popc, r0, simm13, dst);
         }
 
         public Popc(Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Popc, r0, src2, dst);
+            super(Op3s.Popc, r0, src2, dst);
         }
     }
 
     // A.44 Read State Register
 
     @Deprecated
-    public static class Rdy extends Fmt3q {
-
-        public Rdy(SPARCAssembler masm, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 0, dst.encoding());
+    public static class Rdy extends Fmt10 {
+
+        public Rdy(Register dst) {
+            super(Op3s.Rdreg, r0, dst);
         }
     }
 
-    public static class Rdccr extends Fmt3q {
-
-        public Rdccr(SPARCAssembler masm, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 2, dst.encoding());
+    public static class Rdccr extends Fmt10 {
+
+        public Rdccr(Register dst) {
+            super(Op3s.Rdreg, r2, dst);
         }
     }
 
-    public static class Rdasi extends Fmt3q {
-
-        public Rdasi(SPARCAssembler masm, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 3, dst.encoding());
+    public static class Rdasi extends Fmt10 {
+
+        public Rdasi(Register dst) {
+            super(Op3s.Rdreg, r3, dst);
         }
     }
 
-    public static class Rdtick extends Fmt3q {
-
-        public Rdtick(SPARCAssembler masm, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 4, dst.encoding());
+    public static class Rdtick extends Fmt10 {
+
+        public Rdtick(Register dst) {
+            super(Op3s.Rdreg, r4, dst);
         }
     }
 
-    public static class Rdpc extends Fmt3q {
-
-        public Rdpc(SPARCAssembler masm, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 5, dst.encoding());
+    public static class Rdpc extends Fmt10 {
+
+        public Rdpc(Register dst) {
+            super(Op3s.Rdreg, r5, dst);
         }
     }
 
-    public static class Rdfprs extends Fmt3q {
-
-        public Rdfprs(SPARCAssembler masm, Register dst) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Rdreg.getValue(), 6, dst.encoding());
+    public static class Rdfprs extends Fmt10 {
+
+        public Rdfprs(Register dst) {
+            super(Op3s.Rdreg, r6, dst);
         }
     }
 
-    public static class Restore extends Fmt3b {
+    public static class Restore extends Fmt10 {
 
         public Restore(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Restore, src1, src2, dst);
+            super(Op3s.Restore, src1, src2, dst);
         }
     }
 
-    public static class Restored extends Fmt3r {
-
-        public Restored(SPARCAssembler asm) {
-            super(asm, Ops.ArithOp.getValue(), 1, Op3s.Saved.getValue());
+    public static class Restored extends Fmt10 {
+
+        public Restored() {
+            super(Op3s.Saved, r0, r0, r1);
         }
     }
 
-    public static class Return extends Fmt3d {
-
-        public Return(SPARCAssembler masm, Register src1, int simm13) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Rett.getValue(), src1.encoding(), simm13);
-        }
-
-        public Return(SPARCAssembler masm, Register src1, Register src2) {
-            super(masm, Ops.ArithOp.getValue(), Op3s.Rett.getValue(), src1.encoding(), src2.encoding());
+    public static class Return extends Fmt10 {
+
+        public Return(Register src1, int simm13) {
+            super(Op3s.Rett, src1, simm13, r0);
+        }
+
+        public Return(Register src1, Register src2) {
+            super(Op3s.Rett, src1, src2, r0);
         }
     }
 
-    public static class Save extends Fmt3b {
+    public static class Save extends Fmt10 {
 
         public Save(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Save, src1, src2, dst);
+            super(Op3s.Save, src1, src2, dst);
         }
 
         public Save(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Save, src1, simm13, dst);
+            super(Op3s.Save, src1, simm13, dst);
         }
     }
 
-    public static class Saved extends Fmt3r {
-
-        public Saved(SPARCAssembler asm) {
-            super(asm, Ops.ArithOp.getValue(), 0, Op3s.Saved.getValue());
+    public static class Saved extends Fmt10 {
+
+        public Saved() {
+            super(Op3s.Saved, r0, r0, r0);
         }
     }
 
     @Deprecated
-    public static class Sdiv extends Fmt3b {
+    public static class Sdiv extends Fmt10 {
 
         @Deprecated
         public Sdiv(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Sdiv, src1, simm13, dst);
+            super(Op3s.Sdiv, src1, simm13, dst);
         }
 
         @Deprecated
         public Sdiv(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Sdiv, src1, src2, dst);
+            super(Op3s.Sdiv, src1, src2, dst);
         }
     }
 
     @Deprecated
-    public static class Sdivcc extends Fmt3b {
+    public static class Sdivcc extends Fmt10 {
 
         @Deprecated
         public Sdivcc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Sdivcc, src1, simm13, dst);
+            super(Op3s.Sdivcc, src1, simm13, dst);
         }
 
         @Deprecated
         public Sdivcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Sdivcc, src1, src2, dst);
+            super(Op3s.Sdivcc, src1, src2, dst);
         }
     }
 
-    public static class Sdivx extends Fmt3b {
+    public static class Sdivx extends Fmt10 {
 
         public Sdivx(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Sdivx, src1, simm13, dst);
+            super(Op3s.Sdivx, src1, simm13, dst);
         }
 
         public Sdivx(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Sdivx, src1, src2, dst);
+            super(Op3s.Sdivx, src1, src2, dst);
         }
     }
 
@@ -2596,148 +2777,148 @@
         }
     }
 
-    public static class Sir extends Fmt3b {
+    public static class Sir extends Fmt10 {
 
         public Sir(int simm13) {
-            super(Ops.ArithOp, Op3s.Sir, r0, simm13, r15);
+            super(Op3s.Sir, r0, simm13, r15);
         }
     }
 
-    public static class Sll extends Fmt3b {
+    public static class Sll extends Fmt10 {
 
         public Sll(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Sll, src1, simm13, dst);
+            super(Op3s.Sll, src1, simm13, dst);
         }
 
         public Sll(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Sll, src1, src2, dst);
+            super(Op3s.Sll, src1, src2, dst);
         }
     }
 
-    public static class Sllx extends Fmt3b {
+    public static class Sllx extends Fmt10 {
 
         public Sllx(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Sllx, src1, simm13, dst);
+            super(Op3s.Sllx, src1, simm13, dst);
         }
 
         public Sllx(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Sllx, src1, src2, dst);
+            super(Op3s.Sllx, src1, src2, dst);
         }
     }
 
-    public static class Sra extends Fmt3b {
+    public static class Sra extends Fmt10 {
 
         public Sra(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Sra, src1, simm13, dst);
+            super(Op3s.Sra, src1, simm13, dst);
         }
 
         public Sra(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Sra, src1, src2, dst);
+            super(Op3s.Sra, src1, src2, dst);
         }
     }
 
-    public static class Srax extends Fmt3b {
+    public static class Srax extends Fmt10 {
 
         public Srax(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Srax, src1, simm13, dst);
+            super(Op3s.Srax, src1, simm13, dst);
         }
 
         public Srax(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Srax, src1, src2, dst);
+            super(Op3s.Srax, src1, src2, dst);
         }
     }
 
-    public static class Srl extends Fmt3b {
+    public static class Srl extends Fmt10 {
 
         public Srl(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Srl, src1, simm13, dst);
+            super(Op3s.Srl, src1, simm13, dst);
         }
 
         public Srl(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Srl, src1, src2, dst);
+            super(Op3s.Srl, src1, src2, dst);
         }
     }
 
-    public static class Srlx extends Fmt3b {
+    public static class Srlx extends Fmt10 {
 
         public Srlx(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Srlx, src1, simm13, dst);
+            super(Op3s.Srlx, src1, simm13, dst);
         }
 
         public Srlx(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Srlx, src1, src2, dst);
+            super(Op3s.Srlx, src1, src2, dst);
         }
     }
 
-    public static class Stb extends Fmt3b {
+    public static class Stb extends Fmt11 {
 
         public Stb(Register dst, SPARCAddress addr) {
-            super(Ops.LdstOp, Op3s.Stb, addr.getBase(), addr.getDisplacement(), dst);
+            super(Op3s.Stb, addr.getBase(), addr.getDisplacement(), dst);
         }
     }
 
-    public static class Sth extends Fmt3b {
+    public static class Sth extends Fmt11 {
 
         public Sth(Register dst, SPARCAddress addr) {
-            super(Ops.LdstOp, Op3s.Sth, addr.getBase(), addr.getDisplacement(), dst);
+            super(Op3s.Sth, addr.getBase(), addr.getDisplacement(), dst);
         }
     }
 
-    public static class Stw extends Fmt3b {
+    public static class Stw extends Fmt11 {
 
         public Stw(Register dst, SPARCAddress addr) {
-            super(Ops.LdstOp, Op3s.Stw, addr.getBase(), addr.getDisplacement(), dst);
+            super(Op3s.Stw, addr.getBase(), addr.getDisplacement(), dst);
         }
     }
 
-    public static class Stx extends Fmt3b {
+    public static class Stx extends Fmt11 {
 
         public Stx(Register dst, SPARCAddress addr) {
-            super(Ops.LdstOp, Op3s.Stx, addr.getBase(), addr.getDisplacement(), dst);
+            super(Op3s.Stx, addr.getBase(), addr.getDisplacement(), dst);
         }
     }
 
-    public static class Sub extends Fmt3b {
+    public static class Sub extends Fmt10 {
 
         public Sub(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Sub, src1, simm13, dst);
+            super(Op3s.Sub, src1, simm13, dst);
         }
 
         public Sub(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Sub, src1, src2, dst);
+            super(Op3s.Sub, src1, src2, dst);
         }
     }
 
-    public static class Subc extends Fmt3b {
+    public static class Subc extends Fmt10 {
 
         public Subc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Subc, src1, simm13, dst);
+            super(Op3s.Subc, src1, simm13, dst);
         }
 
         public Subc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Subc, src1, src2, dst);
+            super(Op3s.Subc, src1, src2, dst);
         }
     }
 
-    public static class Subcc extends Fmt3b {
+    public static class Subcc extends Fmt10 {
 
         public Subcc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Subcc, src1, simm13, dst);
+            super(Op3s.Subcc, src1, simm13, dst);
         }
 
         public Subcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Subcc, src1, src2, dst);
+            super(Op3s.Subcc, src1, src2, dst);
         }
     }
 
-    public static class Subccc extends Fmt3b {
+    public static class Subccc extends Fmt10 {
 
         public Subccc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Subccc, src1, simm13, dst);
+            super(Op3s.Subccc, src1, simm13, dst);
         }
 
         public Subccc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Subccc, src1, src2, dst);
+            super(Op3s.Subccc, src1, src2, dst);
         }
     }
 
@@ -2752,14 +2933,14 @@
         }
     }
 
-    public static class Taddcc extends Fmt3b {
+    public static class Taddcc extends Fmt10 {
 
         public Taddcc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Taddcc, src1, simm13, dst);
+            super(Op3s.Taddcc, src1, simm13, dst);
         }
 
         public Taddcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Taddcc, src1, src2, dst);
+            super(Op3s.Taddcc, src1, src2, dst);
         }
     }
 
@@ -2884,14 +3065,14 @@
         }
     }
 
-    public static class Tsubcc extends Fmt3b {
+    public static class Tsubcc extends Fmt10 {
 
         public Tsubcc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Tsubcc, src1, simm13, dst);
+            super(Op3s.Tsubcc, src1, simm13, dst);
         }
 
         public Tsubcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Tsubcc, src1, src2, dst);
+            super(Op3s.Tsubcc, src1, src2, dst);
         }
     }
 
@@ -2917,105 +3098,105 @@
         }
     }
 
-    public static class Udivx extends Fmt3b {
+    public static class Udivx extends Fmt10 {
 
         public Udivx(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Udivx, src1, simm13, dst);
+            super(Op3s.Udivx, src1, simm13, dst);
         }
 
         public Udivx(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Udivx, src1, src2, dst);
+            super(Op3s.Udivx, src1, src2, dst);
         }
     }
 
     @Deprecated
-    public static class Wry extends Fmt3b {
+    public static class Wry extends Fmt10 {
 
         @Deprecated
         public Wry(Register src1, int simm13) {
-            super(Ops.ArithOp, Op3s.Wrreg, src1, simm13, r0);
+            super(Op3s.Wrreg, src1, simm13, r0);
         }
 
         @Deprecated
         public Wry(Register src1, Register src2) {
-            super(Ops.ArithOp, Op3s.Wrreg, src1, src2, r0);
+            super(Op3s.Wrreg, src1, src2, r0);
         }
     }
 
-    public static class Wrccr extends Fmt3b {
+    public static class Wrccr extends Fmt10 {
 
         public Wrccr(Register src1, int simm13) {
-            super(Ops.ArithOp, Op3s.Wrreg, src1, simm13, r2);
+            super(Op3s.Wrreg, src1, simm13, r2);
         }
 
         public Wrccr(Register src1, Register src2) {
-            super(Ops.ArithOp, Op3s.Wrreg, src1, src2, r2);
+            super(Op3s.Wrreg, src1, src2, r2);
         }
     }
 
-    public static class Wrasi extends Fmt3b {
+    public static class Wrasi extends Fmt10 {
 
         public Wrasi(Register src1, int simm13) {
-            super(Ops.ArithOp, Op3s.Wrreg, src1, simm13, r3);
+            super(Op3s.Wrreg, src1, simm13, r3);
         }
 
         public Wrasi(Register src1, Register src2) {
-            super(Ops.ArithOp, Op3s.Wrreg, src1, src2, r3);
+            super(Op3s.Wrreg, src1, src2, r3);
         }
     }
 
-    public static class Wrfprs extends Fmt3b {
+    public static class Wrfprs extends Fmt10 {
 
         public Wrfprs(Register src1, int simm13) {
-            super(Ops.ArithOp, Op3s.Wrreg, src1, simm13, r6);
+            super(Op3s.Wrreg, src1, simm13, r6);
         }
 
         public Wrfprs(Register src1, Register src2) {
-            super(Ops.ArithOp, Op3s.Wrreg, src1, src2, r6);
+            super(Op3s.Wrreg, src1, src2, r6);
         }
     }
 
-    public static class Xor extends Fmt3b {
+    public static class Xor extends Fmt10 {
 
         public Xor(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Xor, src1, simm13, dst);
+            super(Op3s.Xor, src1, simm13, dst);
         }
 
         public Xor(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Xor, src1, src2, dst);
+            super(Op3s.Xor, src1, src2, dst);
         }
     }
 
-    public static class Xorcc extends Fmt3b {
+    public static class Xorcc extends Fmt10 {
 
         public Xorcc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Xorcc, src1, simm13, dst);
+            super(Op3s.Xorcc, src1, simm13, dst);
         }
 
         public Xorcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Xorcc, src1, src2, dst);
+            super(Op3s.Xorcc, src1, src2, dst);
         }
     }
 
-    public static class Xnor extends Fmt3b {
+    public static class Xnor extends Fmt10 {
 
         public Xnor(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Xnor, src1, simm13, dst);
+            super(Op3s.Xnor, src1, simm13, dst);
         }
 
         public Xnor(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Xnor, src1, src2, dst);
+            super(Op3s.Xnor, src1, src2, dst);
         }
     }
 
-    public static class Xnorcc extends Fmt3b {
+    public static class Xnorcc extends Fmt10 {
 
         public Xnorcc(Register src1, int simm13, Register dst) {
-            super(Ops.ArithOp, Op3s.Xnorcc, src1, simm13, dst);
+            super(Op3s.Xnorcc, src1, simm13, dst);
         }
 
         public Xnorcc(Register src1, Register src2, Register dst) {
-            super(Ops.ArithOp, Op3s.Xnorcc, src1, src2, dst);
+            super(Op3s.Xnorcc, src1, src2, dst);
         }
     }
 }
--- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java	Tue Jul 09 15:37:50 2013 -0700
@@ -22,14 +22,20 @@
  */
 package com.oracle.graal.asm.sparc;
 
+import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.*;
 
 public class SPARCMacroAssembler extends SPARCAssembler {
 
+    /**
+     * A sentinel value used as a place holder in an instruction stream for an address that will be
+     * patched.
+     */
+    private static final SPARCAddress Placeholder = new SPARCAddress(g0, 0);
+
     public SPARCMacroAssembler(TargetDescription target, RegisterConfig registerConfig) {
         super(target, registerConfig);
     }
@@ -60,12 +66,12 @@
 
     @Override
     public AbstractAddress makeAddress(Register base, int displacement) {
-        throw new InternalError("NYI");
+        return new SPARCAddress(base, displacement);
     }
 
     @Override
     public AbstractAddress getPlaceholder() {
-        throw new InternalError("NYI");
+        return Placeholder;
     }
 
     public static class Bclr extends Andn {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Jul 09 15:37:50 2013 -0700
@@ -25,35 +25,27 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
+import static com.oracle.graal.lir.sparc.SPARCArithmetic.*;
 import static com.oracle.graal.lir.sparc.SPARCBitManipulationOp.IntrinsicOpcode.*;
+import static com.oracle.graal.lir.sparc.SPARCCompare.*;
 import static com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp.IntrinsicOpcode.*;
-import static com.oracle.graal.lir.sparc.SPARCArithmetic.*;
-import static com.oracle.graal.lir.sparc.SPARCCompare.*;
 
-import com.oracle.graal.api.code.CallingConvention;
-import com.oracle.graal.api.code.CodeCacheProvider;
-import com.oracle.graal.api.code.DeoptimizationAction;
-import com.oracle.graal.api.code.ForeignCallLinkage;
-import com.oracle.graal.api.code.StackSlot;
-import com.oracle.graal.api.code.TargetDescription;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.compiler.gen.LIRGenerator;
-import com.oracle.graal.compiler.target.LIRGenLowerable;
-import com.oracle.graal.graph.GraalInternalError;
+import com.oracle.graal.compiler.gen.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.*;
-import com.oracle.graal.lir.sparc.SPARCAddressValue;
+import com.oracle.graal.lir.StandardOp.JumpOp;
+import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.BinaryRegConst;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.Op1Stack;
+import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Reg;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Stack;
-import com.oracle.graal.lir.sparc.SPARCArithmetic.Op2Reg;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.ShiftOp;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary1Op;
 import com.oracle.graal.lir.sparc.SPARCArithmetic.Unary2Op;
-import com.oracle.graal.lir.sparc.SPARCBitManipulationOp;
-import com.oracle.graal.lir.sparc.SPARCBreakpointOp;
-import com.oracle.graal.lir.sparc.SPARCByteSwapOp;
 import com.oracle.graal.lir.sparc.SPARCCompare.CompareOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.BranchOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.CondMoveOp;
@@ -62,7 +54,6 @@
 import com.oracle.graal.lir.sparc.SPARCControlFlow.SequentialSwitchOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.SwitchRangesOp;
 import com.oracle.graal.lir.sparc.SPARCControlFlow.TableSwitchOp;
-import com.oracle.graal.lir.sparc.SPARCMathIntrinsicOp;
 import com.oracle.graal.lir.sparc.SPARCMove.LoadOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MembarOp;
 import com.oracle.graal.lir.sparc.SPARCMove.MoveFromRegOp;
@@ -70,29 +61,21 @@
 import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StackLoadAddressOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
-import com.oracle.graal.lir.sparc.SPARCTestOp;
-import com.oracle.graal.nodes.BreakpointNode;
-import com.oracle.graal.nodes.DeoptimizingNode;
-import com.oracle.graal.nodes.DirectCallTargetNode;
-import com.oracle.graal.nodes.IndirectCallTargetNode;
-import com.oracle.graal.nodes.InfopointNode;
-import com.oracle.graal.nodes.SafepointNode;
-import com.oracle.graal.nodes.StructuredGraph;
-import com.oracle.graal.nodes.ValueNode;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.calc.ConvertNode.Op;
-import com.oracle.graal.nodes.java.CompareAndSwapNode;
+import com.oracle.graal.nodes.java.*;
 
 /**
  * This class implements the SPARC specific portion of the LIR generator.
  */
-public class SPARCLIRGenerator extends LIRGenerator {
+public abstract class SPARCLIRGenerator extends LIRGenerator {
 
-    public static class SPARCSpillMoveFactory implements LIR.SpillMoveFactory {
+    private class SPARCSpillMoveFactory implements LIR.SpillMoveFactory {
 
         @Override
         public LIRInstruction createMove(AllocatableValue result, Value input) {
-            throw new InternalError("NYI");
+            return SPARCLIRGenerator.this.createMove(result, input);
         }
     }
 
@@ -117,20 +100,20 @@
         return result;
     }
 
+    protected SPARCLIRInstruction createMove(AllocatableValue dst, Value src) {
+        if (src instanceof SPARCAddressValue) {
+            // return new LeaOp(dst, (AMD64AddressValue) src);
+            throw new InternalError("NYI");
+        } else if (isRegister(src) || isStackSlot(dst)) {
+            return new MoveFromRegOp(dst, src);
+        } else {
+            return new MoveToRegOp(dst, src);
+        }
+    }
+
     @Override
     public void emitMove(AllocatableValue dst, Value src) {
-        // XXX SPARCAddress loads
-        /*
-         * if (src instanceof SPARCAddressValue) { public LoadOp(Kind kind, AllocatableValue result,
-         * SPARCAddressValue address, LIRFrameState state) {
-         * 
-         * return new LoadOp(result.getKind(), result, (SPARCAddressValue) src); }
-         */
-        if (isRegister(src) || isStackSlot(dst)) {
-            append(new MoveFromRegOp(dst, src));
-        } else {
-            append(new MoveToRegOp(dst, src));
-        }
+        append(createMove(dst, src));
     }
 
     @Override
@@ -300,16 +283,6 @@
     }
 
     @Override
-    protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-        throw new InternalError("NYI");
-    }
-
-    @Override
-    protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
-        throw new InternalError("NYI");
-    }
-
-    @Override
     protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
         throw new InternalError("NYI");
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Tue Jul 09 15:37:50 2013 -0700
@@ -97,13 +97,15 @@
 
         @Override
         public void enter(TargetMethodAssembler tasm) {
-            final int frameSize = tasm.frameMap.frameSize();
+            final int alignment = target.wordSize * 2;
+            final int frameSize = (tasm.frameMap.frameSize() + (alignment - 1)) & ~(alignment - 1);
+            assert frameSize % alignment == 0 : "must preserve 2*wordSize alignment";
 
             SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm;
             if (!isStub) {
                 emitStackOverflowCheck(tasm, false);
             }
-            new Save(sp, frameSize, sp).emit(masm);
+            new Save(sp, -frameSize, sp).emit(masm);
 
             if (ZapStackOnMethodEntry.getValue()) {
                 final int slotSize = 8;
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Tue Jul 09 15:37:50 2013 -0700
@@ -22,29 +22,24 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
-import com.oracle.graal.api.code.CallingConvention;
-import com.oracle.graal.api.code.CodeCacheProvider;
-import com.oracle.graal.api.code.DeoptimizationAction;
-import com.oracle.graal.api.code.StackSlot;
-import com.oracle.graal.api.code.TargetDescription;
-import com.oracle.graal.api.meta.DeoptimizationReason;
-import com.oracle.graal.api.meta.Value;
-import com.oracle.graal.compiler.sparc.SPARCLIRGenerator;
-import com.oracle.graal.hotspot.HotSpotLIRGenerator;
-import com.oracle.graal.hotspot.nodes.DirectCompareAndSwapNode;
-import com.oracle.graal.hotspot.stubs.Stub;
-import com.oracle.graal.lir.FrameMap;
-import com.oracle.graal.lir.LIR;
-import com.oracle.graal.nodes.StructuredGraph;
-import com.oracle.graal.nodes.ValueNode;
+import java.lang.reflect.*;
 
-public class SPARCHotSpotLIRGenerator  extends SPARCLIRGenerator implements HotSpotLIRGenerator {
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.sparc.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nodes.*;
+import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+
+public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator {
 
     public StackSlot deoptimizationRescueSlot;
 
-    public SPARCHotSpotLIRGenerator(StructuredGraph graph,
-            CodeCacheProvider runtime, TargetDescription target,
-            FrameMap frameMap, CallingConvention cc, LIR lir) {
+    public SPARCHotSpotLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
         super(graph, runtime, target, frameMap, cc, lir);
         // TODO Auto-generated constructor stub
     }
@@ -55,8 +50,35 @@
     }
 
     @Override
-    public void emitDeoptimizeCaller(DeoptimizationAction action,
-            DeoptimizationReason reason) {
+    protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
+        InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind();
+        if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) {
+// append(new SPARCHotspotDirectVirtualCallOp(callTarget.target(), result, parameters, temps,
+// callState, invokeKind));
+            throw new InternalError("NYI");
+        } else {
+            assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
+            HotSpotResolvedJavaMethod resolvedMethod = (HotSpotResolvedJavaMethod) callTarget.target();
+            assert !Modifier.isAbstract(resolvedMethod.getModifiers()) : "Cannot make direct call to abstract method.";
+            Constant metaspaceMethod = resolvedMethod.getMetaspaceMethodConstant();
+            append(new SPARCHotspotDirectStaticCallOp(callTarget.target(), result, parameters, temps, callState, invokeKind, metaspaceMethod));
+        }
+    }
+
+    @Override
+    protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) {
+// AllocatableValue metaspaceMethod = AMD64.rbx.asValue();
+// emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode)
+// callTarget).metaspaceMethod()));
+// AllocatableValue targetAddress = AMD64.rax.asValue();
+// emitMove(targetAddress, operand(callTarget.computedAddress()));
+// append(new AMD64IndirectCallOp(callTarget.target(), result, parameters, temps, metaspaceMethod,
+// targetAddress, callState));
+        throw new InternalError("NYI");
+    }
+
+    @Override
+    public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) {
         // TODO Auto-generated method stub
     }
 
@@ -66,8 +88,7 @@
     }
 
     @Override
-    public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc,
-            ValueNode exception, ValueNode exceptionPc) {
+    public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) {
         // TODO Auto-generated method stub
     }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Tue Jul 09 15:37:50 2013 -0700
@@ -75,6 +75,9 @@
     private final Register[] nativeGeneralParameterRegisters;
     private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
 
+    private final Register[] callerSaveRegisters = {g1, g3, g4, g5, o0, o1, o2, o3, o4, o5, o7};
+    private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7};
+
     private final CalleeSaveLayout csl;
 
     private static Register findRegister(String name, Register[] all) {
@@ -124,14 +127,14 @@
         javaGeneralParameterRegisters = new Register[]{i0, i1, i2, i3, i4, i5};
         nativeGeneralParameterRegisters = new Register[]{i0, i1, i2, i3, i4, i5};
 
-        csl = null;
+        csl = new CalleeSaveLayout(architecture, -1, -1, architecture.getWordSize(), calleeSaveRegisters);
         allocatable = initAllocatable(config.useCompressedOops);
         attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters);
     }
 
     @Override
     public Register[] getCallerSaveRegisters() {
-        return getAllocatableRegisters();
+        return callerSaveRegisters;
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java	Tue Jul 09 15:37:50 2013 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.sparc;
+
+import static com.oracle.graal.sparc.SPARC.*;
+import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.sparc.SPARCCall.DirectCallOp;
+import com.oracle.graal.lir.sparc.*;
+import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
+
+/**
+ * A direct call that complies with the conventions for such calls in HotSpot. In particular, for
+ * calls using an inline cache, a MOVE instruction is emitted just prior to the aligned direct call.
+ * This instruction (which moves 0L in G3) is patched by the C++ Graal code to replace the 0L
+ * constant with Universe::non_oop_word(), a special sentinel used for the initial value of the
+ * Klass in an inline cache. It puts the called method into G5 before calling.
+ */
+@Opcode("CALL_DIRECT")
+final class SPARCHotspotDirectStaticCallOp extends DirectCallOp {
+
+    private final Constant metaspaceMethod;
+    private final InvokeKind invokeKind;
+
+    SPARCHotspotDirectStaticCallOp(ResolvedJavaMethod target, Value result, Value[] parameters, Value[] temps, LIRFrameState state, InvokeKind invokeKind, Constant metaspaceMethod) {
+        super(target, result, parameters, temps, state);
+        assert invokeKind == InvokeKind.Static || invokeKind == InvokeKind.Special;
+        this.metaspaceMethod = metaspaceMethod;
+        this.invokeKind = invokeKind;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        // The mark for an invocation that uses an inline cache must be placed at the
+        // instruction that loads the Klass from the inline cache so that the C++ code can find it
+        // and replace the inline 0L value with Universe::non_oop_word()
+// SPARCMove.move(tasm, masm, g5.asValue(Kind.Long), tasm.asLongConstRef(metaspaceMethod));
+
+        new Rdpc(g5).emit(masm);
+        tasm.asLongConstRef(metaspaceMethod);
+        new Ldx(new SPARCAddress(g5, 0), g5).emit(masm);
+        tasm.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL);
+        // XXX move must be patchable!
+        SPARCMove.move(tasm, masm, g3.asValue(Kind.Long), Constant.LONG_0);
+        new Nop().emit(masm);
+        new Nop().emit(masm);
+        new Nop().emit(masm);
+        new Nop().emit(masm);
+        new Nop().emit(masm);
+        new Nop().emit(masm);
+        super.emitCode(tasm, masm);
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java	Tue Jul 09 15:37:50 2013 -0700
@@ -27,10 +27,35 @@
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler;
-import com.oracle.graal.graph.GraalInternalError;
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Add;
+import com.oracle.graal.asm.sparc.SPARCAssembler.And;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Faddd;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fadds;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fdivd;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fdivs;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fdtoi;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fmuld;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fmuls;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fnegd;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fnegs;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fstoi;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fsubd;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fsubs;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Mulx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Sdivx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Sll;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Sllx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Sra;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Srax;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Srl;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Srlx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Sub;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Xor;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.asm.TargetMethodAssembler;
+import com.oracle.graal.lir.asm.*;
 
 public enum SPARCArithmetic {
     // @formatter:off
@@ -64,7 +89,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             SPARCMove.move(tasm, masm, result, x);
             emit(tasm, masm, opcode, result, y, null);
         }
@@ -92,7 +117,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             SPARCMove.move(tasm, masm, result, x);
             emit(tasm, masm, opcode, result, x, null);
         }
@@ -114,7 +139,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             emit(masm, opcode, result);
         }
     }
@@ -132,7 +157,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             emit(tasm, masm, opcode, result, x, null);
         }
     }
@@ -152,7 +177,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             emit(tasm, masm, opcode, result, x, y, null);
         }
 
@@ -178,7 +203,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             emit(tasm, masm, opcode, result, x, y, null);
         }
 
@@ -204,7 +229,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             emit(tasm, masm, opcode, result, x, y, null);
         }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBitManipulationOp.java	Tue Jul 09 15:37:50 2013 -0700
@@ -51,7 +51,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
         Register dst = ValueUtil.asIntReg(result);
         Register tmp = null;  // ??
         if (ValueUtil.isRegister(input)) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java	Tue Jul 09 15:37:50 2013 -0700
@@ -52,7 +52,7 @@
 
     @Override
     @SuppressWarnings("unused")
-    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) {
-        new Trap(asm, ST_RESERVED_FOR_USER_0);
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+        new Trap(masm, ST_RESERVED_FOR_USER_0);
     }
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCByteSwapOp.java	Tue Jul 09 15:37:50 2013 -0700
@@ -39,7 +39,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
         SPARCMove.move(tasm, masm, result, input);
         switch (input.getKind()) {
         // case Int:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCall.java	Tue Jul 09 15:37:50 2013 -0700
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.lir.sparc;
+
+import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import static com.oracle.graal.sparc.SPARC.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class SPARCCall {
+
+    public abstract static class CallOp extends SPARCLIRInstruction {
+
+        @Def({REG, ILLEGAL}) protected Value result;
+        @Use({REG, STACK}) protected Value[] parameters;
+        @Temp protected Value[] temps;
+        @State protected LIRFrameState state;
+
+        public CallOp(Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+            this.result = result;
+            this.parameters = parameters;
+            this.state = state;
+            this.temps = temps;
+            assert temps != null;
+        }
+
+        @Override
+        public boolean destroysCallerSavedRegisters() {
+            return true;
+        }
+    }
+
+    public abstract static class MethodCallOp extends CallOp {
+
+        protected final ResolvedJavaMethod callTarget;
+
+        public MethodCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+            super(result, parameters, temps, state);
+            this.callTarget = callTarget;
+        }
+
+    }
+
+    @Opcode("CALL_DIRECT")
+    public static class DirectCallOp extends MethodCallOp {
+
+        public DirectCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+            super(callTarget, result, parameters, temps, state);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+            directCall(tasm, masm, callTarget, null, true, state);
+        }
+    }
+
+    @Opcode("CALL_INDIRECT")
+    public static class IndirectCallOp extends MethodCallOp {
+
+        @Use({REG}) protected Value targetAddress;
+
+        public IndirectCallOp(ResolvedJavaMethod callTarget, Value result, Value[] parameters, Value[] temps, Value targetAddress, LIRFrameState state) {
+            super(callTarget, result, parameters, temps, state);
+            this.targetAddress = targetAddress;
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+            indirectCall(tasm, masm, asRegister(targetAddress), callTarget, state);
+        }
+
+        @Override
+        protected void verify() {
+            super.verify();
+            assert isRegister(targetAddress) : "The current register allocator cannot handle variables to be used at call sites, it must be in a fixed register for now";
+        }
+    }
+
+    public abstract static class ForeignCallOp extends CallOp {
+
+        protected final ForeignCallLinkage callTarget;
+
+        public ForeignCallOp(ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+            super(result, parameters, temps, state);
+            this.callTarget = callTarget;
+        }
+
+        @Override
+        public boolean destroysCallerSavedRegisters() {
+            return callTarget.destroysRegisters();
+        }
+    }
+
+    @Opcode("NEAR_FOREIGN_CALL")
+    public static class DirectNearForeignCallOp extends ForeignCallOp {
+
+        public DirectNearForeignCallOp(ForeignCallLinkage linkage, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+            super(linkage, result, parameters, temps, state);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+            directCall(tasm, masm, callTarget, null, false, state);
+        }
+    }
+
+    @Opcode("FAR_FOREIGN_CALL")
+    public static class DirectFarForeignCallOp extends ForeignCallOp {
+
+        @Temp({REG}) protected AllocatableValue callTemp;
+
+        public DirectFarForeignCallOp(LIRGeneratorTool gen, ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+            super(callTarget, result, parameters, temps, state);
+            callTemp = gen.newVariable(Kind.Long);
+        }
+
+        @Override
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+            directCall(tasm, masm, callTarget, ((RegisterValue) callTemp).getRegister(), false, state);
+        }
+    }
+
+    public static void directCall(TargetMethodAssembler tasm, SPARCMacroAssembler masm, InvokeTarget callTarget, Register scratch, boolean align, LIRFrameState info) {
+        if (align) {
+            // We don't need alignment on SPARC.
+        }
+        int before = masm.codeBuffer.position();
+        if (scratch != null) {
+// // offset might not fit a 32-bit immediate, generate an
+// // indirect call with a 64-bit immediate
+// masm.movq(scratch, 0L);
+// masm.call(scratch);
+// } else {
+// masm.call();
+        }
+        new Call(0).emit(masm);
+        int after = masm.codeBuffer.position();
+        tasm.recordDirectCall(before, after, callTarget, info);
+        tasm.recordExceptionHandlers(after, info);
+// masm.ensureUniquePC();
+        new Nop().emit(masm);  // delay slot
+    }
+
+    public static void directJmp(TargetMethodAssembler tasm, SPARCMacroAssembler masm, InvokeTarget target) {
+        int before = masm.codeBuffer.position();
+// masm.jmp(0, true);
+        int after = masm.codeBuffer.position();
+        tasm.recordDirectCall(before, after, target, null);
+// masm.ensureUniquePC();
+        new Nop().emit(masm);  // delay slot
+        throw new InternalError("NYI");
+    }
+
+    public static void indirectCall(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
+        int before = masm.codeBuffer.position();
+        new Jmpl(dst, 0, r15).emit(masm);
+        int after = masm.codeBuffer.position();
+        tasm.recordIndirectCall(before, after, callTarget, info);
+        tasm.recordExceptionHandlers(after, info);
+// masm.ensureUniquePC();
+        new Nop().emit(masm);  // delay slot
+    }
+}
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCCompare.java	Tue Jul 09 15:37:50 2013 -0700
@@ -49,7 +49,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             emit(tasm, masm, opcode, x, y);
         }
 
@@ -62,7 +62,7 @@
         }
     }
 
-    public static void emit(TargetMethodAssembler tasm, SPARCAssembler masm, SPARCCompare opcode, Value x, Value y) {
+    public static void emit(TargetMethodAssembler tasm, SPARCMacroAssembler masm, SPARCCompare opcode, Value x, Value y) {
         if (isRegister(y)) {
             switch (opcode) {
                 case ICMP:
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Tue Jul 09 15:37:50 2013 -0700
@@ -52,7 +52,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             switch (condition) {
                 case GT:
                     // FIXME xcc is wrong! It depends on the compare.
@@ -93,7 +93,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             cmove(tasm, masm, result, false, condition, false, trueValue, falseValue);
         }
     }
@@ -116,12 +116,12 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue);
         }
     }
 
-    private static void cmove(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
+    private static void cmove(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, boolean isFloat, ConditionFlag condition, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
         // check that we don't overwrite an input operand before it is used.
         assert !result.equals(trueValue);
 
@@ -137,7 +137,7 @@
         }
     }
 
-    private static void cmove(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, ConditionFlag cond, Value other) {
+    private static void cmove(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, ConditionFlag cond, Value other) {
         if (!isRegister(other)) {
             SPARCMove.move(tasm, masm, result, other);
             throw new InternalError("result should be scratch");
@@ -213,7 +213,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             new Ret().emit(masm);
             // On SPARC we always leave the frame.
             tasm.frameContext.leave(tasm);
@@ -239,7 +239,7 @@
 
         @Override
         @SuppressWarnings("unused")
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             if (key.getKind() == Kind.Int) {
                 Register intKey = asIntReg(key);
                 for (int i = 0; i < keyConstants.length; i++) {
@@ -309,7 +309,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             assert isSorted(lowKeys) && isSorted(highKeys);
 
             Label actualDefaultTarget = defaultTarget == null ? new Label() : defaultTarget.label();
@@ -387,7 +387,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             tableswitch(tasm, masm, lowKey, defaultTarget, targets, asIntReg(index), asLongReg(scratch));
         }
     }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCLIRInstruction.java	Tue Jul 09 15:37:50 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,14 +27,14 @@
 import com.oracle.graal.lir.asm.*;
 
 /**
- * Convenience class to provide SPARCAssembler for the {@link #emitCode} method.
+ * Convenience class to provide SPARCMacroAssembler for the {@link #emitCode} method.
  */
 public abstract class SPARCLIRInstruction extends LIRInstruction {
 
     @Override
     public final void emitCode(TargetMethodAssembler tasm) {
-        emitCode(tasm, (SPARCAssembler) tasm.asm);
+        emitCode(tasm, (SPARCMacroAssembler) tasm.asm);
     }
 
-    public abstract void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm);
+    public abstract void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm);
 }
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMathIntrinsicOp.java	Tue Jul 09 15:37:50 2013 -0700
@@ -25,8 +25,8 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler;
 import com.oracle.graal.asm.sparc.SPARCAssembler.Fsqrtd;
+import com.oracle.graal.asm.sparc.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
@@ -48,10 +48,10 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) {
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
         switch (opcode) {
             case SQRT:
-                new Fsqrtd(asDoubleReg(result), asDoubleReg(input)).emit(asm);
+                new Fsqrtd(asDoubleReg(result), asDoubleReg(input)).emit(masm);
                 break;
             case LOG:
             case LOG10:
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Tue Jul 09 15:37:50 2013 -0700
@@ -24,19 +24,31 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.graal.sparc.SPARC.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.asm.sparc.SPARCAssembler.*;
-import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsh;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lduw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Membar;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stb;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Sth;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setuw;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.asm.*;
 
-import static com.oracle.graal.sparc.SPARC.*;
-
 public class SPARCMove {
 
     public static class LoadOp extends SPARCLIRInstruction {
@@ -54,7 +66,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             SPARCAddress addr = address.toAddress();
             switch (kind) {
                 case Byte:
@@ -96,8 +108,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) {
-            new Membar(barriers).emit(asm);
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+            new Membar(barriers).emit(masm);
         }
     }
 
@@ -113,7 +125,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             move(tasm, masm, getResult(), getInput());
         }
 
@@ -140,7 +152,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             move(tasm, masm, getResult(), getInput());
         }
 
@@ -167,7 +179,7 @@
 
         @Override
         @SuppressWarnings("unused")
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             tasm.recordImplicitException(masm.codeBuffer.position(), state);
             new Ldx(new SPARCAddress(asRegister(input), 0), r0);
         }
@@ -184,8 +196,8 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler asm) {
-            new Ldx((SPARCAddress) tasm.asAddress(slot), asLongReg(result)).emit(asm);
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
+            new Ldx((SPARCAddress) tasm.asAddress(slot), asLongReg(result)).emit(masm);
         }
     }
 
@@ -204,7 +216,7 @@
         }
 
         @Override
-        public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+        public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
             assert isRegister(input);
             SPARCAddress addr = address.toAddress();
             switch (kind) {
@@ -231,10 +243,18 @@
         }
     }
 
-    public static void move(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, Value input) {
+    public static void move(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Value input) {
         if (isRegister(input)) {
             if (isRegister(result)) {
                 reg2reg(masm, result, input);
+            } else if (isStackSlot(result)) {
+                reg2stack(tasm, masm, result, input);
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+        } else if (isStackSlot(input)) {
+            if (isRegister(result)) {
+                stack2reg(tasm, masm, result, input);
             } else {
                 throw GraalInternalError.shouldNotReachHere();
             }
@@ -268,8 +288,38 @@
         }
     }
 
+    private static void reg2stack(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Value input) {
+        SPARCAddress dest = (SPARCAddress) tasm.asAddress(result);
+        switch (input.getKind()) {
+            case Int:
+                new Stw(asRegister(input), dest).emit(masm);
+                break;
+            case Long:
+            case Float:
+            case Double:
+            case Object:
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static void stack2reg(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Value input) {
+        SPARCAddress src = (SPARCAddress) tasm.asAddress(input);
+        switch (input.getKind()) {
+            case Int:
+                new Ldsw(src, asRegister(result)).emit(masm);
+                break;
+            case Long:
+            case Float:
+            case Double:
+            case Object:
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
     @SuppressWarnings("unused")
-    private static void const2reg(TargetMethodAssembler tasm, SPARCAssembler masm, Value result, Constant input) {
+    private static void const2reg(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Constant input) {
         switch (input.getKind().getStackKind()) {
             case Int:
                 if (tasm.runtime.needsDataPatch(input)) {
@@ -281,7 +331,7 @@
                 if (tasm.runtime.needsDataPatch(input)) {
                     tasm.recordDataReferenceInCode(input, 0, true);
                 }
-                new Setx(masm, input.asInt(), null, asRegister(result));
+                new Setx(masm, input.asLong(), null, asRegister(result));
                 break;
             case Object:
                 if (input.isNull()) {
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCTestOp.java	Tue Jul 09 15:37:50 2013 -0700
@@ -43,7 +43,7 @@
     }
 
     @Override
-    public void emitCode(TargetMethodAssembler tasm, SPARCAssembler masm) {
+    public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
         if (isRegister(y)) {
             switch (x.getKind()) {
                 case Int:
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Tue Jul 09 15:37:21 2013 -0700
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Tue Jul 09 15:37:50 2013 -0700
@@ -113,9 +113,9 @@
     public static final Register fp = i6;
     public static final Register sp = o6;
 
-    public static final Register[] gprRegisters = {
+    public static final Register[] cpuRegisters = {
         r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
-         r8,  r9, r10, r11, r12, r13, r14, r15,
+        r8,  r9,  r10, r11, r12, r13, r14, r15,
         r16, r17, r18, r19, r20, r21, r22, r23,
         r24, r25, r26, r27, r28, r29, r30, r31
     };
@@ -131,7 +131,7 @@
     public static final Register f7 = new Register(39, 7, "f7", FPU);
 
     public static final Register[] allRegisters = {
-        // GPR
+        // CPU
         r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
         r8,  r9, r10, r11, r12, r13, r14, r15,
        r16, r17, r18, r19, r20, r21, r22, r23,
@@ -140,15 +140,12 @@
         f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,
     };
 
+    // @formatter:on
+
     public SPARC() {
-        super("SPARC",
-              8,
-              ByteOrder.BIG_ENDIAN,
-              allRegisters,
-              LOAD_STORE | STORE_STORE,
-              1,
-              r31.encoding + 1,
-              8);
+        // The return address doesn't have an extra slot in the frame so we pass 0 for the return
+        // address size.
+        super("SPARC", 8, ByteOrder.BIG_ENDIAN, allRegisters, LOAD_STORE | STORE_STORE, 1, r31.encoding + 1, 0);
     }
 
     @Override
@@ -176,12 +173,17 @@
                     return true;
             }
         }
-
         return false;
     }
 
     @Override
     public PlatformKind getLargestStorableKind(RegisterCategory category) {
-        throw new InternalError("NYI");
+        if (category == CPU) {
+            return Kind.Long;
+        } else if (category == FPU) {
+            return Kind.Double;
+        } else {
+            return Kind.Illegal;
+        }
     }
 }