/*
 * Copyright (c) 2009, 2016, 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 org.graalvm.compiler.asm.sparc;

import static org.graalvm.compiler.asm.sparc.SPARCAssembler.CC.Icc;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.ConditionFlag.Always;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Add;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Addc;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Addcc;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.And;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Andcc;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Andn;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Andncc;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Casa;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Casxa;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Flushw;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Fpop1;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Fpop2;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Impdep1;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Jmpl;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Lddf;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Ldf;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Ldsb;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Ldsh;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Ldsw;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Ldub;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Lduh;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Lduw;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Lduwa;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Ldx;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Ldxa;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Membar;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Movcc;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Mulx;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Or;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Popc;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Prefetch;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Rd;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Restore;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Save;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Sdivx;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Sll;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Sllx;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Sra;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Srax;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Srl;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Srlx;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Stb;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Stdf;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Stf;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Sth;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Stw;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Stx;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Stxa;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Sub;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Subcc;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Udivx;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Wr;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Xnor;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Xor;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Op3s.Xorcc;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fabsd;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fabss;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Faddd;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fadds;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fdivd;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fdivs;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fdtoi;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fdtos;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fdtox;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fitod;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fitos;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fmovd;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fmovs;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fmuld;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fmuls;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fnegd;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fnegs;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fpadd32;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fsmuld;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fsqrtd;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fsqrts;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fsrc2d;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fsrc2s;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fstod;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fstoi;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fstox;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fsubd;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fsubs;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fxtod;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fxtos;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fzerod;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Fzeros;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Movdtox;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Movstosw;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Movwtos;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.Movxtod;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Opfs.UMulxhi;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Ops.ArithOp;
import static org.graalvm.compiler.asm.sparc.SPARCAssembler.Ops.LdstOp;
import static java.lang.String.format;
import static jdk.vm.ci.sparc.SPARC.CPU;
import static jdk.vm.ci.sparc.SPARC.FPUd;
import static jdk.vm.ci.sparc.SPARC.FPUs;
import static jdk.vm.ci.sparc.SPARC.g0;
import static jdk.vm.ci.sparc.SPARC.g2;
import static jdk.vm.ci.sparc.SPARC.g5;
import static jdk.vm.ci.sparc.SPARC.g7;
import static jdk.vm.ci.sparc.SPARC.o7;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.graalvm.compiler.asm.Assembler;
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.NumUtil;
import org.graalvm.compiler.common.PermanentBailoutException;
import org.graalvm.compiler.debug.GraalError;

import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.sparc.SPARC;
import jdk.vm.ci.sparc.SPARC.CPUFeature;
import jdk.vm.ci.sparc.SPARCKind;

/**
 * This class implements an assembler that can encode most SPARC instructions.
 */
public abstract class SPARCAssembler extends Assembler {

    /**
     * Constructs an assembler for the SPARC architecture.
     */
    public SPARCAssembler(TargetDescription target) {
        super(target);
    }

    /**
     * Size of an SPARC assembler instruction in Bytes.
     */
    public static final int INSTRUCTION_SIZE = 4;

    /**
     * Size in bytes which are cleared by stxa %g0, [%rd] ASI_ST_BLKINIT_PRIMARY.
     */
    public static final int BLOCK_ZERO_LENGTH = 64;

    public static final int CCR_ICC_SHIFT = 0;
    public static final int CCR_XCC_SHIFT = 4;
    public static final int CCR_V_SHIFT = 1;

    public static final int MEMBAR_LOAD_LOAD = 1;
    public static final int MEMBAR_STORE_LOAD = 2;
    public static final int MEMBAR_LOAD_STORE = 3;
    public static final int MEMBAR_STORE_STORE = 4;

    private static final Ops[] OPS;
    private static final Op2s[] OP2S;
    private static final Op3s[][] OP3S;

    private ArrayList<Integer> delaySlotOptimizationPoints = new ArrayList<>(5);

    static {
        Ops[] ops = Ops.values();
        OPS = new Ops[ops.length];
        for (Ops op : ops) {
            OPS[op.value] = op;
        }
        Op2s[] op2s = Op2s.values();
        OP2S = new Op2s[op2s.length];
        for (Op2s op2 : op2s) {
            OP2S[op2.value] = op2;
        }
        OP3S = new Op3s[2][64];
        for (Op3s op3 : Op3s.values()) {
            if (op3.value >= 1 << 6) {
                throw new RuntimeException("Error " + op3 + " " + op3.value);
            }
            OP3S[op3.op.value & 1][op3.value] = op3;
        }
    }

    public enum Ops {
        // @formatter:off
        BranchOp(0b00),
        CallOp(0b01),
        ArithOp(0b10),
        LdstOp(0b11);
        // @formatter:on

        private final int value;

        Ops(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public boolean appliesTo(int instructionWord) {
            int opShift = 30;
            return (instructionWord >>> opShift) == value;
        }
    }

    public enum Op2s {
        // Checkstyle: stop
        // @formatter:off
        Illtrap(0b000),
        Bpr    (0b011),
        Fb     (0b110),
        Fbp    (0b101),
        Br     (0b010),
        Bp     (0b001),
        Cb     (0b111),
        Sethi  (0b100);
        // @formatter:on
        // Checkstyle: resume

        private final int value;

        Op2s(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public static Op2s byValue(int value) {
            return OP2S[value];
        }
    }

    private static final int COMMUTATIVE = 1;
    private static final int BINARY = 2;
    private static final int UNARY = 4;
    private static final int VOID_IN = 8;

    public enum Op3s {
        // Checkstyle: stop
        // @formatter:off
        Add(0x00, "add", ArithOp, BINARY | COMMUTATIVE),
        And(0x01, "and", ArithOp, BINARY | COMMUTATIVE),
        Or(0x02, "or", ArithOp, BINARY | COMMUTATIVE),
        Xor(0x03, "xor", ArithOp, BINARY | COMMUTATIVE),
        Sub(0x04, "sub", ArithOp, BINARY),
        Andn(0x05, "andn", ArithOp, BINARY | COMMUTATIVE),
        Orn(0x06, "orn", ArithOp, BINARY | COMMUTATIVE),
        Xnor(0x07, "xnor", ArithOp, BINARY | COMMUTATIVE),
        Addc(0x08, "addc", ArithOp, BINARY | COMMUTATIVE),
        Mulx(0x09, "mulx", ArithOp, BINARY | COMMUTATIVE),
        Umul(0x0A, "umul", ArithOp, BINARY | COMMUTATIVE),
        Smul(0x0B, "smul", ArithOp, BINARY | COMMUTATIVE),
        Subc(0x0C, "subc", ArithOp, BINARY),
        Udivx(0x0D, "udivx", ArithOp, BINARY),
        Udiv(0x0E, "udiv", ArithOp, BINARY),
        Sdiv(0x0F, "sdiv", ArithOp, BINARY),

        Addcc(0x10, "addcc", ArithOp, BINARY | COMMUTATIVE),
        Andcc(0x11, "andcc", ArithOp, BINARY | COMMUTATIVE),
        Orcc(0x12, "orcc", ArithOp, BINARY | COMMUTATIVE),
        Xorcc(0x13, "xorcc", ArithOp, BINARY | COMMUTATIVE),
        Subcc(0x14, "subcc", ArithOp, BINARY),
        Andncc(0x15, "andncc", ArithOp, BINARY | COMMUTATIVE),
        Orncc(0x16, "orncc", ArithOp, BINARY | COMMUTATIVE),
        Xnorcc(0x17, "xnorcc", ArithOp, BINARY | COMMUTATIVE),
        Addccc(0x18, "addccc", ArithOp, BINARY | COMMUTATIVE),

        Umulcc(0x1A, "umulcc", ArithOp, BINARY | COMMUTATIVE),
        Smulcc(0x1B, "smulcc", ArithOp, BINARY | COMMUTATIVE),
        Subccc(0x1C, "subccc", ArithOp, BINARY),
        Udivcc(0x1E, "udivcc", ArithOp, BINARY),
        Sdivcc(0x1F, "sdivcc", ArithOp, BINARY),

        Mulscc(0x24, "mulscc", ArithOp, BINARY | COMMUTATIVE),
        Sll(0x25, "sll", ArithOp, BINARY),
        Sllx(0x25, "sllx", ArithOp, BINARY),
        Srl(0x26, "srl", ArithOp, BINARY),
        Srlx(0x26, "srlx", ArithOp, BINARY),
        Sra(0x27, "srax", ArithOp, BINARY),
        Srax(0x27, "srax", ArithOp, BINARY),
        Membar(0x28, "membar", ArithOp),

        Flushw(0x2B, "flushw", ArithOp),
        Movcc(0x2C, "movcc", ArithOp),
        Sdivx(0x2D, "sdivx", ArithOp, BINARY),
        Popc(0x2E, "popc", ArithOp, UNARY),
        Movr(0x2F, "movr", ArithOp, BINARY),

        Fpop1(0b11_0100, "fpop1", ArithOp),
        Fpop2(0b11_0101, "fpop2", ArithOp),
        Impdep1(0b11_0110, "impdep1", ArithOp),
        Impdep2(0b11_0111, "impdep2", ArithOp),
        Jmpl(0x38, "jmpl", ArithOp),
        Rett(0x39, "rett", ArithOp),
        Trap(0x3a, "trap", ArithOp),
        Flush(0x3b, "flush", ArithOp),
        Save(0x3c, "save", ArithOp),
        Restore(0x3d, "restore", ArithOp),
        Retry(0x3e, "retry", ArithOp),


        Casa(0b111100, "casa", LdstOp),
        Casxa(0b111110, "casxa", LdstOp),
        Prefetch(0b101101, "prefetch", LdstOp),
        Prefetcha(0b111101, "prefetcha", LdstOp),

        Lduw  (0b00_0000, "lduw", LdstOp),
        Ldub  (0b00_0001, "ldub", LdstOp),
        Lduh  (0b00_0010, "lduh", LdstOp),
        Stw   (0b00_0100, "stw", LdstOp),
        Stb   (0b00_0101, "stb", LdstOp),
        Sth   (0b00_0110, "sth", LdstOp),
        Ldsw  (0b00_1000, "ldsw", LdstOp),
        Ldsb  (0b00_1001, "ldsb", LdstOp),
        Ldsh  (0b00_1010, "ldsh", LdstOp),
        Ldx   (0b00_1011, "ldx", LdstOp),
        Stx   (0b00_1110, "stx", LdstOp),

        Ldf   (0b10_0000, "ldf", LdstOp),
        Ldfsr (0b10_0001, "ldfsr", LdstOp),
        Ldaf  (0b10_0010, "ldaf", LdstOp),
        Lddf  (0b10_0011, "lddf", LdstOp),
        Stf   (0b10_0100, "stf", LdstOp),
        Stfsr (0b10_0101, "stfsr", LdstOp),
        Staf  (0b10_0110, "staf", LdstOp),
        Stdf  (0b10_0111, "stdf", LdstOp),

        Stba  (0b01_0101, "stba", LdstOp),
        Stha  (0b01_0110, "stha", LdstOp),
        Stwa  (0b01_0100, "stwa", LdstOp),
        Stxa  (0b01_1110, "stxa", LdstOp),

        Ldsba  (0b01_1001, "ldsba", LdstOp),
        Ldsha  (0b01_1010, "ldsha", LdstOp),
        Ldswa  (0b01_1000, "ldswa", LdstOp),
        Lduba  (0b01_0001, "lduba", LdstOp),
        Lduha  (0b01_0010, "lduha", LdstOp),
        Lduwa (0b01_0000, "lduwa", LdstOp),

        Ldxa  (0b01_1011, "ldxa", LdstOp),

        Rd    (0b10_1000, "rd", ArithOp),
        Wr    (0b11_0000, "wr", ArithOp),

        Tcc(0b11_1010, "tcc", ArithOp);

        // @formatter:on
        // Checkstyle: resume

        private final int value;
        private final String operator;
        private final Ops op;
        private final int flags;

        Op3s(int value, String name, Ops op) {
            this(value, name, op, 0);
        }

        Op3s(int value, String name, Ops op, int flags) {
            this.value = value;
            this.operator = name;
            this.op = op;
            this.flags = flags;
        }

        public int getValue() {
            return value;
        }

        public String getOperator() {
            return operator;
        }

        public boolean throwsException() {
            if (op == LdstOp) {
                return true;
            }
            switch (this) {
                case Udiv:
                case Udivx:
                case Sdiv:
                case Sdivx:
                case Udivcc:
                case Sdivcc:
                    return true;
                default:
                    return false;
            }
        }

        public boolean isBinary() {
            return (flags & BINARY) != 0;
        }

        public boolean isUnary() {
            return (flags & UNARY) != 0;
        }

        public boolean isCommutative() {
            return (flags & COMMUTATIVE) != 0;
        }
    }

    public enum Opfs {
        // @formatter:off

        Fmovs(0b0_0000_0001, "fmovs", Fpop1, UNARY),
        Fmovd(0b0_0000_0010, "fmovd", Fpop1, UNARY),
        Fmovq(0b0_0000_0011, "fmovq", Fpop1, UNARY),
        Fnegs(0x05, "fnegs", Fpop1, UNARY),
        Fnegd(0x06, "fnegd", Fpop1, UNARY),
        Fnegq(0x07, "fnegq", Fpop1, UNARY),
        Fabss(0x09, "fabss", Fpop1, UNARY),
        Fabsd(0x0A, "fabsd", Fpop1, UNARY),
        Fabsq(0x0B, "fabsq", Fpop1, UNARY),

        // start VIS1
        Fpadd32(0x52, "fpadd32", Impdep1, BINARY | COMMUTATIVE),
        Fzerod(0x60, "fzerod", Impdep1, VOID_IN),
        Fzeros(0x61, "fzeros", Impdep1, VOID_IN),
        Fsrc2d(0x78, "fsrc2d", Impdep1, UNARY),
        Fsrc2s(0x79, "fsrc2s", Impdep1, UNARY),
        // end VIS1

        // start VIS3
        Movdtox(0x110, "movdtox", Impdep1, UNARY),
        Movstouw(0x111, "movstouw", Impdep1, UNARY),
        Movstosw(0x113, "movstosw", Impdep1, UNARY),
        Movxtod(0x118, "movxtod", Impdep1, UNARY),
        Movwtos(0b1_0001_1001, "movwtos", Impdep1, UNARY),
        UMulxhi(0b0_0001_0110, "umulxhi", Impdep1, BINARY | COMMUTATIVE),
        // end VIS3

        Fadds(0x41, "fadds", Fpop1, BINARY | COMMUTATIVE),
        Faddd(0x42, "faddd", Fpop1, BINARY | COMMUTATIVE),
        Fsubs(0x45, "fsubs", Fpop1, BINARY),
        Fsubd(0x46, "fsubd", Fpop1, BINARY),
        Fmuls(0x49, "fmuls", Fpop1, BINARY | COMMUTATIVE),
        Fmuld(0x4A, "fmuld", Fpop1, BINARY | COMMUTATIVE),
        Fdivs(0x4D, "fdivs", Fpop1, BINARY),
        Fdivd(0x4E, "fdivd", Fpop1, BINARY),

        Fsqrts(0x29, "fsqrts", Fpop1, UNARY),
        Fsqrtd(0x2A, "fsqrtd", Fpop1, UNARY),

        Fsmuld(0x69, "fsmuld", Fpop1, BINARY | COMMUTATIVE),

        Fstoi(0xD1, "fstoi", Fpop1, UNARY),
        Fdtoi(0xD2, "fdtoi", Fpop1, UNARY),
        Fstox(0x81, "fstox", Fpop1, UNARY),
        Fdtox(0x82, "fdtox", Fpop1, UNARY),
        Fxtos(0x84, "fxtos", Fpop1, UNARY),
        Fxtod(0x88, "fxtod", Fpop1, UNARY),
        Fitos(0xC4, "fitos", Fpop1, UNARY),
        Fdtos(0xC6, "fdtos", Fpop1, UNARY),
        Fitod(0xC8, "fitod", Fpop1, UNARY),
        Fstod(0xC9, "fstod", Fpop1, UNARY),


        Fcmps(0x51, "fcmps", Fpop2, BINARY),
        Fcmpd(0x52, "fcmpd", Fpop2, BINARY);

        // @formatter:on

        private final int value;
        private final String operator;
        private final Op3s op3;
        private final int flags;

        Opfs(int value, String op, Op3s op3, int flags) {
            this.value = value;
            this.operator = op;
            this.op3 = op3;
            this.flags = flags;
        }

        public int getValue() {
            return value;
        }

        public String getOperator() {
            return operator;
        }

        public boolean isBinary() {
            return (flags & BINARY) != 0;
        }

        public boolean isUnary() {
            return (flags & UNARY) != 0;
        }

        public boolean isCommutative() {
            return (flags & COMMUTATIVE) != 0;
        }
    }

    public enum OpfLow {
        Fmovscc(0b00_0001, "fmovscc", Fpop2),
        Fmovdcc(0b00_0010, "fmovdcc", Fpop2);

        private final int value;
        private final String operator;
        private final Op3s op3;

        OpfLow(int value, String op, Op3s op3) {
            this.value = value;
            this.operator = op;
            this.op3 = op3;
        }

        @Override
        public String toString() {
            return operator;
        }
    }

    public enum Annul {
        ANNUL(1),
        NOT_ANNUL(0);
        public final int flag;

        Annul(int flag) {
            this.flag = flag;
        }
    }

    public enum BranchPredict {
        PREDICT_TAKEN(1),
        PREDICT_NOT_TAKEN(0);
        public final int flag;

        BranchPredict(int flag) {
            this.flag = flag;
        }
    }

    public enum MembarMask {
        // @formatter:off

        StoreStore(1 << 3, "storestore"),
        LoadStore(1 << 2, "loadstore"),
        StoreLoad(1 << 1, "storeload"),
        LoadLoad(1 << 0, "loadload"),
        Sync(1 << 6, "sync"),
        MemIssue(1 << 5, "memissue"),
        LookAside(1 << 4, "lookaside");

        // @formatter:on

        private final int value;
        private final String operator;

        MembarMask(int value, String op) {
            this.value = value;
            this.operator = op;
        }

        public int getValue() {
            return value | 0x2000;
        }

        public String getOperator() {
            return operator;
        }
    }

    /**
     * Condition Codes to use for instruction.
     */
    public enum CC {
        // @formatter:off
        /**
         * Condition is considered as 32bit operation condition.
         */
        Icc(0b00, "icc", false),
        /**
         * Condition is considered as 64bit operation condition.
         */
        Xcc(0b10, "xcc", false),
        Fcc0(0b00, "fcc0", true),
        Fcc1(0b01, "fcc1", true),
        Fcc2(0b10, "fcc2", true),
        Fcc3(0b11, "fcc3", true);

        // @formatter:on

        private final int value;
        private final String operator;
        private boolean isFloat;

        CC(int value, String op, boolean isFloat) {
            this.value = value;
            this.operator = op;
            this.isFloat = isFloat;
        }

        public int getValue() {
            return value;
        }

        public String getOperator() {
            return operator;
        }

        public static CC forKind(PlatformKind kind) {
            if (kind.equals(SPARCKind.XWORD)) {
                return Xcc;
            } else if (kind.equals(SPARCKind.WORD)) {
                return Icc;
            } else if (kind.equals(SPARCKind.SINGLE) || kind.equals(SPARCKind.DOUBLE)) {
                return Fcc0;
            } else {
                throw new IllegalArgumentException("Unknown kind: " + kind);
            }
        }
    }

    public enum ConditionFlag {
        // @formatter:off

        // for FBfcc & FBPfcc instruction
        F_Never(0, "f_never"),
        F_NotEqual(1, "f_notEqual"),
        F_LessOrGreater(2, "f_lessOrGreater"),
        F_UnorderedOrLess(3, "f_unorderedOrLess"),
        F_Less(4, "f_less"),
        F_UnorderedOrGreater(5, "f_unorderedOrGreater"),
        F_Greater(6, "f_greater"),
        F_Unordered(7, "f_unordered"),
        F_Always(8, "f_always"),
        F_Equal(9, "f_equal"),
        F_UnorderedOrEqual(10, "f_unorderedOrEqual"),
        F_GreaterOrEqual(11, "f_greaterOrEqual"),
        F_UnorderedGreaterOrEqual(12, "f_unorderedGreaterOrEqual"),
        F_LessOrEqual(13, "f_lessOrEqual"),
        F_UnorderedOrLessOrEqual(14, "f_unorderedOrLessOrEqual"),
        F_Ordered(15, "f_ordered"),

        // for integers
        Never(0, "never"),
        Equal(1, "equal", true),
        Zero(1, "zero"),
        LessEqual(2, "lessEqual", true),
        Less(3, "less", true),
        LessEqualUnsigned(4, "lessEqualUnsigned", true),
        LessUnsigned(5, "lessUnsigned", true),
        CarrySet(5, "carrySet"),
        Negative(6, "negative", true),
        OverflowSet(7, "overflowSet", true),
        Always(8, "always"),
        NotEqual(9, "notEqual", true),
        NotZero(9, "notZero"),
        Greater(10, "greater", true),
        GreaterEqual(11, "greaterEqual", true),
        GreaterUnsigned(12, "greaterUnsigned", true),
        GreaterEqualUnsigned(13, "greaterEqualUnsigned", true),
        CarryClear(13, "carryClear"),
        Positive(14, "positive", true),
        OverflowClear(15, "overflowClear", true);

        // @formatter:on

        private final int value;
        private final String operator;
        private boolean forCBcond = false;

        ConditionFlag(int value, String op) {
            this(value, op, false);
        }

        ConditionFlag(int value, String op, boolean cbcond) {
            this.value = value;
            this.operator = op;
            this.forCBcond = cbcond;
        }

        public boolean isCBCond() {
            return forCBcond;
        }

        public int getValue() {
            return value;
        }

        public String getOperator() {
            return operator;
        }

        public ConditionFlag negate() {
            //@formatter:off
            switch (this) {
                case F_Never                  : return F_Always;
                case F_Always                 : return F_Never;
                case F_NotEqual               : return F_Equal;
                case F_Equal                  : return F_NotEqual;
                case F_LessOrGreater          : return F_UnorderedOrEqual;
                case F_UnorderedOrEqual       : return F_LessOrGreater;
                case F_Less                   : return F_UnorderedGreaterOrEqual;
                case F_UnorderedGreaterOrEqual: return F_Less;
                case F_LessOrEqual            : return F_UnorderedOrGreater;
                case F_UnorderedOrGreater     : return F_LessOrEqual;
                case F_Greater                : return F_UnorderedOrLessOrEqual;
                case F_UnorderedOrLessOrEqual : return F_Greater;
                case F_GreaterOrEqual         : return F_UnorderedOrLess;
                case F_UnorderedOrLess        : return F_GreaterOrEqual;
                case F_Unordered              : return F_Ordered;
                case F_Ordered                : return F_Unordered;
                case Never                    : return Always;
                case Always                   : return Never;
                case Equal                    : return NotEqual;
                case NotEqual                 : return Equal;
                case Zero                     : return NotZero;
                case NotZero                  : return Zero;
                case LessEqual                : return Greater;
                case Greater                  : return LessEqual;
                case Less                     : return GreaterEqual;
                case GreaterEqual             : return Less;
                case LessEqualUnsigned        : return GreaterUnsigned;
                case GreaterUnsigned          : return LessEqualUnsigned;
                case LessUnsigned             : return GreaterEqualUnsigned;
                case GreaterEqualUnsigned     : return LessUnsigned;
                case CarrySet                 : return CarryClear;
                case CarryClear               : return CarrySet;
                case Negative                 : return Positive;
                case Positive                 : return Negative;
                case OverflowSet              : return OverflowClear;
                case OverflowClear            : return OverflowSet;
                default:
                    throw new InternalError();
            }
            //@formatter:on
        }

        public ConditionFlag mirror() {
            switch (this) {
            //@formatter:off
                case F_Less                   : return F_Greater;
                case F_Greater                : return F_Less;
                case F_LessOrEqual            : return F_GreaterOrEqual;
                case F_UnorderedGreaterOrEqual: return F_UnorderedOrLessOrEqual;
                case F_UnorderedOrGreater     : return F_UnorderedOrLess;
                case F_UnorderedOrLessOrEqual : return F_UnorderedGreaterOrEqual;
                case F_GreaterOrEqual         : return F_LessOrEqual;
                case F_UnorderedOrLess        : return F_UnorderedOrGreater;
                case LessEqual                : return GreaterEqual;
                case Greater                  : return Less;
                case Less                     : return Greater;
                case GreaterEqual             : return LessEqual;
                case LessEqualUnsigned        : return GreaterEqualUnsigned;
                case GreaterUnsigned          : return LessUnsigned;
                case LessUnsigned             : return GreaterUnsigned;
                case GreaterEqualUnsigned     : return LessEqualUnsigned;
                default:
                    return this;
                //@formatter:on
            }
        }

    }

    public enum RCondition {
        // @formatter:off

        Rc_z(0b001, "rc_z"),
        Rc_lez(0b010, "rc_lez"),
        Rc_lz(0b011, "rc_lz"),
        Rc_nz(0b101, "rc_nz"),
        Rc_gz(0b110, "rc_gz"),
        Rc_gez(0b111, "rc_gez"),
        Rc_last(Rc_gez.getValue(), "rc_last");

        // @formatter:on

        private final int value;
        private final String operator;

        RCondition(int value, String op) {
            this.value = value;
            this.operator = op;
        }

        public int getValue() {
            return value;
        }

        public String getOperator() {
            return operator;
        }
    }

    /**
     * Represents the <b>Address Space Identifier</b> defined in the SPARC architecture.
     */
    public enum Asi {
        // @formatter:off

        INVALID(-1),
        ASI_PRIMARY(0x80),
        ASI_PRIMARY_NOFAULT(0x82),
        ASI_PRIMARY_LITTLE(0x88),
        // Block initializing store
        ASI_ST_BLKINIT_PRIMARY(0xE2),
        // Most-Recently-Used (MRU) BIS variant
        ASI_ST_BLKINIT_MRU_PRIMARY(0xF2);

        // @formatter:on

        private final int value;

        Asi(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public boolean isValid() {
            return value != INVALID.getValue();
        }
    }

    public enum Fcn {
        SeveralWritesAndPossiblyReads(2),
        SeveralReadsWeak(0),
        OneRead(1),
        OneWrite(3),
        Page(4),
        NearestUnifiedCache(17),
        SeveralReadsStrong(20),
        OneReadStrong(21),
        SeveralWritesAndPossiblyReadsStrong(22),
        OneWriteStrong(23);

        private final int value;

        Fcn(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

    /**
     * Specifies various bit fields used in SPARC instructions.
     */
    @SuppressWarnings("unused")
    public abstract static class BitSpec {
        private static final BitSpec op = new ContinousBitSpec(31, 30, "op");
        private static final BitSpec op2 = new ContinousBitSpec(24, 22, "op2");
        private static final BitSpec op3 = new ContinousBitSpec(24, 19, "op3");
        private static final BitSpec opf = new ContinousBitSpec(13, 5, "opf");
        private static final BitSpec opfLow = new ContinousBitSpec(10, 5, "opfLow");
        private static final BitSpec opfCC = new ContinousBitSpec(13, 11, "opfCC");
        private static final BitSpec opfCond = new ContinousBitSpec(17, 14, "opfCond");
        private static final BitSpec rd = new ContinousBitSpec(29, 25, "rd");
        private static final BitSpec rs1 = new ContinousBitSpec(18, 14, "rs1");
        private static final BitSpec rs2 = new ContinousBitSpec(4, 0, "rs2");
        private static final BitSpec simm13 = new ContinousBitSpec(12, 0, true, "simm13");
        private static final BitSpec shcnt32 = new ContinousBitSpec(4, 0, "shcnt32");
        private static final BitSpec shcnt64 = new ContinousBitSpec(5, 0, "shcnt64");
        private static final BitSpec imm22 = new ContinousBitSpec(21, 0, "imm22");
        private static final BitSpec immAsi = new ContinousBitSpec(12, 5, "immASI");
        private static final BitSpec i = new ContinousBitSpec(13, 13, "i");
        private static final BitSpec disp19 = new ContinousBitSpec(18, 0, true, "disp19");
        private static final BitSpec disp22 = new ContinousBitSpec(21, 0, true, "disp22");
        private static final BitSpec disp30 = new ContinousBitSpec(29, 0, true, "disp30");
        private static final BitSpec a = new ContinousBitSpec(29, 29, "a");
        private static final BitSpec p = new ContinousBitSpec(19, 19, "p");
        private static final BitSpec x = new ContinousBitSpec(12, 12, "x");
        private static final BitSpec cond = new ContinousBitSpec(28, 25, "cond");
        private static final BitSpec rcond = new ContinousBitSpec(27, 25, "rcond");
        private static final BitSpec cc = new ContinousBitSpec(21, 20, "cc");
        private static final BitSpec fcc = new ContinousBitSpec(26, 25, "cc");
        private static final BitSpec d16lo = new ContinousBitSpec(13, 0, "d16lo");
        private static final BitSpec d16hi = new ContinousBitSpec(21, 20, true, "d16hi");
        private static final BitSpec d16 = new CompositeBitSpec(d16hi, d16lo);
        // Movcc
        private static final BitSpec movccLo = new ContinousBitSpec(12, 11, "cc_lo");
        private static final BitSpec movccHi = new ContinousBitSpec(18, 18, "cc_hi");
        private static final BitSpec movccCond = new ContinousBitSpec(17, 14, "cond");
        private static final BitSpec simm11 = new ContinousBitSpec(10, 0, true, "simm11");

        // CBCond
        private static final BitSpec cLo = new ContinousBitSpec(27, 25, "cLo");
        private static final BitSpec cHi = new ContinousBitSpec(29, 29, "cHi");
        private static final BitSpec c = new CompositeBitSpec(cHi, cLo);
        private static final BitSpec cbcond = new ContinousBitSpec(28, 28, "cbcond");
        private static final BitSpec cc2 = new ContinousBitSpec(21, 21, "cc2");
        private static final BitSpec d10Lo = new ContinousBitSpec(12, 5, "d10Lo");
        private static final BitSpec d10Hi = new ContinousBitSpec(20, 19, true, "d10Hi");
        private static final BitSpec d10 = new CompositeBitSpec(d10Hi, d10Lo);
        private static final BitSpec simm5 = new ContinousBitSpec(4, 0, true, "simm5");

        protected final boolean signExtend;

        public BitSpec(boolean signExtend) {
            super();
            this.signExtend = signExtend;
        }

        public final boolean isSignExtend() {
            return signExtend;
        }

        public abstract int setBits(int word, int value);

        public abstract int getBits(int word);

        public abstract int getWidth();

        public abstract boolean valueFits(int value);
    }

    public static final class ContinousBitSpec extends BitSpec {
        private final int hiBit;
        private final int lowBit;
        private final int width;
        private final int mask;
        private final String name;

        public ContinousBitSpec(int hiBit, int lowBit, String name) {
            this(hiBit, lowBit, false, name);
        }

        public ContinousBitSpec(int hiBit, int lowBit, boolean signExt, String name) {
            super(signExt);
            this.hiBit = hiBit;
            this.lowBit = lowBit;
            this.width = hiBit - lowBit + 1;
            mask = ((1 << width) - 1) << lowBit;
            this.name = name;
        }

        @Override
        public int setBits(int word, int value) {
            assert valueFits(value) : String.format("Value 0x%x for field %s does not fit.", value, this);
            return (word & ~mask) | ((value << lowBit) & mask);
        }

        @Override
        public int getBits(int word) {
            if (signExtend) {
                return ((word & mask) << (31 - hiBit)) >> (32 - width);
            } else {
                return (word & mask) >>> lowBit;
            }
        }

        @Override
        public int getWidth() {
            return width;
        }

        @Override
        public String toString() {
            return String.format("%s [%d:%d]", name, hiBit, lowBit);
        }

        @Override
        public boolean valueFits(int value) {
            if (signExtend) {
                return isSimm(value, getWidth());
            } else {
                return isImm(value, getWidth());
            }
        }
    }

    public static final class CompositeBitSpec extends BitSpec {
        private final BitSpec left;
        private final int leftWidth;
        private final BitSpec right;
        private final int rightWidth;
        private final int width;

        public CompositeBitSpec(BitSpec left, BitSpec right) {
            super(left.isSignExtend());
            assert !right.isSignExtend() : String.format("Right field %s must not be sign extended", right);
            this.left = left;
            this.leftWidth = left.getWidth();
            this.right = right;
            this.rightWidth = right.getWidth();
            this.width = leftWidth + rightWidth;
        }

        @Override
        public int getBits(int word) {
            int l = left.getBits(word);
            int r = right.getBits(word);
            return (l << rightWidth) | r;
        }

        @Override
        public int setBits(int word, int value) {
            int l = leftBits(value);
            int r = rightBits(value);
            return left.setBits(right.setBits(word, r), l);
        }

        private int leftBits(int value) {
            return getBits(value, width - 1, rightWidth, signExtend);
        }

        private int rightBits(int value) {
            return getBits(value, rightWidth - 1, 0, false);
        }

        @Override
        public int getWidth() {
            return width;
        }

        @Override
        public String toString() {
            return String.format("CompositeBitSpec[%s, %s]", left, right);
        }

        @Override
        public boolean valueFits(int value) {
            int l = leftBits(value);
            int r = rightBits(value);
            return left.valueFits(l) && right.valueFits(r);
        }

        private static int getBits(int inst, int hiBit, int lowBit, boolean signExtended) {
            int shifted = inst >> lowBit;
            if (signExtended) {
                return shifted;
            } else {
                return shifted & ((1 << (hiBit - lowBit + 1)) - 1);
            }
        }
    }

    public static class BitKey {
        private final BitSpec spec;
        private final int value;

        public BitKey(BitSpec spec, int value) {
            super();
            this.spec = spec;
            this.value = value;
        }

        @Override
        public String toString() {
            return String.format("BitKey %s=%s", spec, value);
        }
    }

    /**
     * Represents a prefix tree of {@link BitSpec} objects to find the most accurate SPARCOp.
     */
    public static final class BitKeyIndex {
        private final BitSpec spec;
        private final Map<Integer, BitKeyIndex> nodes;
        private SPARCOp op;

        public BitKeyIndex(SPARCOp op) {
            assert op != null;
            this.op = op;
            this.nodes = null;
            this.spec = null;
        }

        public BitKeyIndex(BitSpec spec) {
            assert spec != null;
            this.op = null;
            this.nodes = new HashMap<>(4);
            this.spec = spec;
        }

        /**
         * Adds operation to the index.
         *
         * @param keys Ordered by the importance
         * @param operation Operation represented by this list of keys
         */
        private void addOp(List<BitKey[]> keys, SPARCOp operation) {
            assert keys.size() > 0;
            BitKey[] firstKeys = keys.get(0);
            for (BitKey first : firstKeys) {
                assert first.spec.equals(spec) : first.spec + " " + spec;
                BitKeyIndex node;
                if (keys.size() == 1) {
                    if (nodes.containsKey(first.value)) {
                        node = nodes.get(first.value);
                        assert node.op == null : node + " " + keys;
                        node.op = operation;
                    } else {
                        assert !nodes.containsKey(first.value) : "Index must be unique. Existing key: " + nodes.get(first.value);
                        node = new BitKeyIndex(operation);
                    }
                } else {
                    node = nodes.get(first.value);
                    BitKey[] next = keys.get(1);
                    if (node == null) {
                        for (int i = 1; i < next.length; i++) {
                            assert next[i - 1].spec.equals(next[i].spec) : "All spec on this node must equal";
                        }
                        node = new BitKeyIndex(next[0].spec);
                    }
                    node.addOp(keys.subList(1, keys.size()), operation);
                }
                nodes.put(first.value, node);
            }
        }

        /**
         * Finds the best matching {@link SPARCOp} for this instruction.
         */
        public SPARCOp find(int inst) {
            if (nodes != null) {
                int key = spec.getBits(inst);
                BitKeyIndex sub = nodes.get(key);
                if (sub == null) {
                    if (op != null) {
                        return op;
                    } else {
                        throw new RuntimeException(String.format("%s 0x%x, 0x%x %s", spec, inst, key, nodes));
                    }
                }
                return sub.find(inst);
            } else {
                return this.op;
            }
        }

        @Override
        public String toString() {
            return this.op == null ? this.spec + ": " + this.nodes : this.op.toString();
        }
    }

    public static final Bpcc BPCC = new Bpcc(Op2s.Bp);
    public static final Bpcc FBPCC = new Bpcc(Op2s.Fbp);
    public static final CBCond CBCOND = new CBCond();
    public static final Bpr BPR = new Bpr();
    public static final Br BR = new Br();
    public static final Sethi SETHI = new Sethi();
    public static final FMOVcc FMOVSCC = new FMOVcc(OpfLow.Fmovscc);
    public static final FMOVcc FMOVDCC = new FMOVcc(OpfLow.Fmovdcc);
    public static final MOVicc MOVicc = new MOVicc();
    public static final OpfOp OPF = new OpfOp();
    public static final Op3Op OP3 = new Op3Op();
    public static final SPARCOp LDST = new SPARCOp(Ops.LdstOp);
    public static final SPARCOp BRANCH = new SPARCOp(Ops.BranchOp);
    public static final SPARCOp CALL = new SPARCOp(Ops.CallOp);
    private static final BitKeyIndex INDEX = new BitKeyIndex(BitSpec.op);

    static {
        for (SPARCOp op : SPARCOp.OPS) {
            INDEX.addOp(op.getKeys(), op);
        }
    }

    public static SPARCOp getSPARCOp(int inst) {
        return INDEX.find(inst);
    }

    /**
     * Represents a class of SPARC instruction and gives methods to modify its fields.
     */
    public static class SPARCOp {
        private final Ops op;
        private final BitKey opKey;
        private List<BitKey[]> keyFields;
        private static final List<SPARCOp> OPS = new ArrayList<>();

        public SPARCOp(Ops op) {
            super();
            this.op = op;
            this.opKey = new BitKey(BitSpec.op, op.value);
            OPS.add(this);
        }

        protected int setBits(int word) {
            return BitSpec.op.setBits(word, op.value);
        }

        public boolean match(int inst) {
            for (BitKey[] keys : keyFields) {
                for (BitKey k : keys) {
                    if (k.spec.getBits(inst) != k.value) {
                        return false;
                    }
                }
            }
            return true;
        }

        protected List<BitKey[]> getKeys() {
            if (keyFields == null) {
                keyFields = new ArrayList<>(4);
                keyFields.add(new BitKey[]{opKey});
            }
            return keyFields;
        }

        public Ops getOp(int inst) {
            return SPARCAssembler.OPS[BitSpec.op.getBits(inst)];
        }

        @Override
        public String toString() {
            String name = getClass().getName();
            name = name.substring(name.lastIndexOf(".") + 1);
            return name + "[op: " + op + "]";
        }
    }

    /**
     * Base class for control transfer operations; provides access to the disp field.
     */
    public abstract static class ControlTransferOp extends SPARCOp {
        private final Op2s op2;
        private final boolean delaySlot;
        private final BitSpec disp;
        private final BitKey[] op2Key;

        private ControlTransferOp(Ops op, Op2s op2, boolean delaySlot, BitSpec disp) {
            super(op);
            this.op2 = op2;
            this.delaySlot = delaySlot;
            this.disp = disp;
            this.op2Key = new BitKey[]{new BitKey(BitSpec.op2, op2.value)};
        }

        public boolean hasDelaySlot() {
            return delaySlot;
        }

        @Override
        protected int setBits(int word) {
            return BitSpec.op2.setBits(super.setBits(word), op2.value);
        }

        protected int setDisp(int inst, SPARCMacroAssembler masm, Label lab) {
            if (lab.isBound()) {
                int d = (lab.position() - masm.position()) / 4;
                return setDisp(inst, d);
            } else {
                masm.patchUnbound(lab);
                return inst;
            }
        }

        public int setDisp(int inst, int d) {
            assert this.match(inst);
            if (!isValidDisp(d)) {
                throw new PermanentBailoutException("Too large displacement 0x%x in field %s in instruction %s", d, this.disp, this);
            }
            return this.disp.setBits(inst, d);
        }

        public boolean isValidDisp(int d) {
            return this.disp.valueFits(d);
        }

        public int setAnnul(int inst, boolean a) {
            return BitSpec.a.setBits(inst, a ? 1 : 0);
        }

        @Override
        protected List<BitKey[]> getKeys() {
            List<BitKey[]> keys = super.getKeys();
            keys.add(op2Key);
            return keys;
        }

        public int getDisp(int inst) {
            return this.disp.getBits(inst);
        }

        public abstract boolean isAnnulable(int inst);

        public abstract boolean isConditional(int inst);
    }

    public static final class Bpcc extends ControlTransferOp {
        public Bpcc(Op2s op2) {
            super(Ops.BranchOp, op2, true, BitSpec.disp19);
        }

        public void emit(SPARCMacroAssembler masm, CC cc, ConditionFlag cf, Annul annul, BranchPredict p, Label lab) {
            int inst = setBits(0);
            inst = BitSpec.a.setBits(inst, annul.flag);
            inst = BitSpec.cond.setBits(inst, cf.value);
            inst = BitSpec.cc.setBits(inst, cc.value);
            inst = BitSpec.p.setBits(inst, p.flag);
            masm.insertNopAfterCBCond();
            masm.emitInt(setDisp(inst, masm, lab));
        }

        @Override
        public boolean isAnnulable(int inst) {
            return isConditional(inst);
        }

        @Override
        public boolean isConditional(int inst) {
            int cond = BitSpec.cond.getBits(inst);
            return cond != ConditionFlag.Always.value && cond != ConditionFlag.Never.value;
        }
    }

    public static final class Br extends ControlTransferOp {
        public Br() {
            super(Ops.BranchOp, Op2s.Br, true, BitSpec.disp22);
        }

        @Override
        public boolean isAnnulable(int inst) {
            return isConditional(inst);
        }

        @Override
        public boolean isConditional(int inst) {
            int cond = BitSpec.cond.getBits(inst);
            return cond != ConditionFlag.Always.value && cond != ConditionFlag.Never.value;
        }

        public void emit(SPARCMacroAssembler masm, ConditionFlag cond, Annul a, Label lab) {
            int inst = setBits(0);
            inst = BitSpec.cond.setBits(inst, cond.value);
            inst = BitSpec.a.setBits(inst, a.flag);
            masm.insertNopAfterCBCond();
            masm.emitInt(setDisp(inst, masm, lab));
        }
    }

    public static final class Bpr extends ControlTransferOp {
        private static final BitKey CBCOND_KEY = new BitKey(BitSpec.cbcond, 0);

        public Bpr() {
            super(Ops.BranchOp, Op2s.Bpr, true, BitSpec.d16);
        }

        public void emit(SPARCMacroAssembler masm, RCondition rcond, Annul a, BranchPredict p, Register rs1, Label lab) {
            int inst = setBits(0);
            inst = BitSpec.rcond.setBits(inst, rcond.value);
            inst = BitSpec.a.setBits(inst, a.flag);
            inst = BitSpec.p.setBits(inst, p.flag);
            inst = BitSpec.rs1.setBits(inst, rs1.encoding);
            masm.insertNopAfterCBCond();
            masm.emitInt(setDisp(inst, masm, lab));
        }

        @Override
        protected List<BitKey[]> getKeys() {
            List<BitKey[]> keys = super.getKeys();
            keys.add(new BitKey[]{CBCOND_KEY});
            return keys;
        }

        @Override
        public boolean isAnnulable(int inst) {
            return isConditional(inst);
        }

        @Override
        public boolean isConditional(int inst) {
            int cond = BitSpec.cond.getBits(inst);
            return cond != ConditionFlag.Always.value && cond != ConditionFlag.Never.value;
        }
    }

    public static final class CBCond extends ControlTransferOp {
        private static final BitKey CBCOND_KEY = new BitKey(BitSpec.cbcond, 1);

        private CBCond() {
            super(Ops.BranchOp, Op2s.Bpr, false, BitSpec.d10);
        }

        @Override
        protected List<BitKey[]> getKeys() {
            List<BitKey[]> keys = super.getKeys();
            keys.add(new BitKey[]{CBCOND_KEY});
            return keys;
        }

        public void emit(SPARCMacroAssembler masm, ConditionFlag cf, boolean cc2, Register rs1, Register rs2, Label lab) {
            int inst = setBits(0, cf, cc2, rs1);
            inst = BitSpec.rs2.setBits(inst, rs2.encoding);
            inst = BitSpec.i.setBits(inst, 0);
            masm.insertNopAfterCBCond();
            emit(masm, lab, inst);
        }

        public void emit(SPARCMacroAssembler masm, ConditionFlag cf, boolean cc2, Register rs1, int simm5, Label lab) {
            int inst = setBits(0, cf, cc2, rs1);
            inst = BitSpec.simm5.setBits(inst, simm5);
            inst = BitSpec.i.setBits(inst, 1);
            emit(masm, lab, inst);
        }

        private void emit(SPARCMacroAssembler masm, Label lab, int baseInst) {
            int inst = baseInst;
            masm.insertNopAfterCBCond();
            masm.emitInt(setDisp(inst, masm, lab));
        }

        private int setBits(int base, ConditionFlag cf, boolean cc2, Register rs1) {
            int inst = super.setBits(base);
            inst = BitSpec.rs1.setBits(inst, rs1.encoding);
            inst = BitSpec.cc2.setBits(inst, cc2 ? 1 : 0);
            inst = BitSpec.c.setBits(inst, cf.value);
            return BitSpec.cbcond.setBits(inst, 1);
        }

        @Override
        public boolean isAnnulable(int inst) {
            return false;
        }

        @Override
        public boolean isConditional(int inst) {
            return true;
        }
    }

    public static class Op2Op extends SPARCOp {
        private final Op2s op2;
        private final BitKey op2Key;

        public Op2Op(Ops op, Op2s op2) {
            super(op);
            this.op2 = op2;
            op2Key = new BitKey(BitSpec.op2, op2.value);
        }

        @Override
        protected int setBits(int word) {
            int result = super.setBits(word);
            return BitSpec.op2.setBits(result, op2.value);
        }

        @Override
        protected List<BitKey[]> getKeys() {
            List<BitKey[]> keys = super.getKeys();
            keys.add(new BitKey[]{op2Key});
            return keys;
        }
    }

    public static final class Sethi extends Op2Op {
        public Sethi() {
            super(Ops.BranchOp, Op2s.Sethi);
        }

        public static Register getRS1(int word) {
            int regNum = BitSpec.rs1.getBits(word);
            return SPARC.cpuRegisters.get(regNum);
        }

        public static int getImm22(int word) {
            return BitSpec.imm22.getBits(word);
        }

        public static boolean isNop(int inst) {
            return getRS1(inst).equals(g0) && getImm22(inst) == 0;
        }
    }

    public static final class Op3Op extends SPARCOp {
        public Op3Op() {
            super(ArithOp);
        }

        public Op3s getOp3(int inst) {
            assert match(inst);
            return OP3S[ArithOp.value & 1][BitSpec.op3.getBits(inst)];
        }

        public static void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, Register rs2, Register rd) {
            int instruction = setBits(0, opcode, rs1, rd);
            instruction = BitSpec.rs2.setBits(instruction, rs2.encoding);
            instruction = BitSpec.i.setBits(instruction, 0);
            masm.emitInt(instruction);
        }

        public static void emit(SPARCMacroAssembler masm, Op3s opcode, Register rs1, int simm13, Register rd) {
            int instruction = setBits(0, opcode, rs1, rd);
            instruction = BitSpec.i.setBits(instruction, 1);
            BitSpec immediateSpec;
            switch (opcode) {
                case Sllx:
                case Srlx:
                case Srax:
                    immediateSpec = BitSpec.shcnt64;
                    break;
                case Sll:
                case Srl:
                case Sra:
                    immediateSpec = BitSpec.shcnt32;
                    break;
                default:
                    immediateSpec = BitSpec.simm13;
                    break;
            }
            instruction = immediateSpec.setBits(instruction, simm13);
            masm.emitInt(instruction);
        }

        private static int setBits(int instruction, Op3s op3, Register rs1, Register rd) {
            assert op3.op.equals(ArithOp);
            int tmp = BitSpec.op3.setBits(instruction, op3.value);
            switch (op3) {
                case Sllx:
                case Srlx:
                case Srax:
                    tmp = BitSpec.x.setBits(tmp, 1);
                    break;
            }
            tmp = BitSpec.op.setBits(tmp, op3.op.value);
            tmp = BitSpec.rd.setBits(tmp, rd.encoding);
            return BitSpec.rs1.setBits(tmp, rs1.encoding);
        }
    }

    /**
     * Used for interfacing FP and GP conditional move instructions.
     */
    public interface CMOV {
        void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, Register rs2, Register rd);

        void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, int simm11, Register rd);
    }

    public static final class MOVicc extends SPARCOp implements CMOV {
        private static final Op3s op3 = Movcc;

        public MOVicc() {
            super(ArithOp);
        }

        @Override
        public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, Register rs2, Register rd) {
            int inst = setBits(0, condition, cc, rd);
            inst = BitSpec.rs2.setBits(inst, rs2.encoding());
            masm.emitInt(inst);
        }

        @Override
        public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, int simm11, Register rd) {
            int inst = setBits(0, condition, cc, rd);
            inst = BitSpec.i.setBits(inst, 1);
            inst = BitSpec.simm11.setBits(inst, simm11);
            masm.emitInt(inst);
        }

        protected int setBits(int word, ConditionFlag condition, CC cc, Register rd) {
            int inst = super.setBits(word);
            inst = BitSpec.rd.setBits(inst, rd.encoding());
            inst = BitSpec.op3.setBits(inst, op3.value);
            inst = BitSpec.movccCond.setBits(inst, condition.value);
            inst = BitSpec.movccLo.setBits(inst, cc.value);
            return BitSpec.movccHi.setBits(inst, cc.isFloat ? 0 : 1);
        }

        @Override
        protected List<BitKey[]> getKeys() {
            List<BitKey[]> keys = super.getKeys();
            keys.add(new BitKey[]{new BitKey(BitSpec.op3, op3.value)});
            return keys;
        }
    }

    public static final class FMOVcc extends SPARCOp implements CMOV {
        private OpfLow opfLow;

        public FMOVcc(OpfLow opfLow) {
            super(ArithOp);
            this.opfLow = opfLow;
        }

        @Override
        public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, Register rs2, Register rd) {
            int inst = setBits(0);
            inst = BitSpec.rd.setBits(inst, rd.encoding());
            inst = BitSpec.op3.setBits(inst, opfLow.op3.value);
            inst = BitSpec.opfCond.setBits(inst, condition.value);
            inst = BitSpec.opfCC.setBits(inst, cc.value);
            inst = BitSpec.opfLow.setBits(inst, opfLow.value);
            inst = BitSpec.rs2.setBits(inst, rs2.encoding());
            masm.emitInt(inst);
        }

        @Override
        public void emit(SPARCMacroAssembler masm, ConditionFlag condition, CC cc, int simm11, Register rd) {
            throw new IllegalArgumentException("FMOVCC cannot be used with immediate value");
        }

        @Override
        protected List<BitKey[]> getKeys() {
            List<BitKey[]> keys = super.getKeys();
            keys.add(new BitKey[]{new BitKey(BitSpec.op3, opfLow.op3.value)});
            keys.add(new BitKey[]{new BitKey(BitSpec.opfLow, opfLow.value)});
            return keys;
        }
    }

    public static final class OpfOp extends SPARCOp {

        private BitKey[] op3Keys;

        public OpfOp(BitKey... op3Keys) {
            super(ArithOp);
            this.op3Keys = op3Keys;
        }

        public OpfOp() {
            // @formatter:off
            this(new BitKey[]{
                            new BitKey(BitSpec.op3, Op3s.Fpop1.value),
                            new BitKey(BitSpec.op3, Op3s.Fpop2.value),
                            new BitKey(BitSpec.op3, Op3s.Impdep1.value),
                            new BitKey(BitSpec.op3, Op3s.Impdep2.value)});
            // @formatter:on
        }

        public static void emit(SPARCMacroAssembler masm, Opfs opf, Register rs1, Register rs2, Register rd) {
            int instruction = setBits(0, opf, rs1, rs2);
            instruction = BitSpec.rd.setBits(instruction, rd.encoding);
            instruction = BitSpec.i.setBits(instruction, 0);
            masm.emitInt(instruction);
        }

        public static void emitFcmp(SPARCMacroAssembler masm, Opfs opf, CC cc, Register rs1, Register rs2) {
            assert opf.equals(Opfs.Fcmpd) || opf.equals(Opfs.Fcmps) : opf;
            int instruction = setBits(0, opf, rs1, rs2);
            instruction = BitSpec.fcc.setBits(instruction, cc.value);
            masm.emitInt(instruction);
        }

        private static int setBits(int instruction, Opfs opf, Register rs1, Register rs2) {
            int tmp = BitSpec.op.setBits(instruction, opf.op3.op.value);
            tmp = BitSpec.op3.setBits(tmp, opf.op3.value);
            tmp = BitSpec.opf.setBits(tmp, opf.value);
            tmp = BitSpec.rs1.setBits(tmp, rs1.encoding);
            return BitSpec.rs2.setBits(tmp, rs2.encoding);
        }

        @Override
        protected List<BitKey[]> getKeys() {
            List<BitKey[]> keys = super.getKeys();
            keys.add(op3Keys);
            // @formatter:on
            return keys;
        }
    }

    public static boolean isCPURegister(Register... regs) {
        for (Register reg : regs) {
            if (!isCPURegister(reg)) {
                return false;
            }
        }
        return true;
    }

    public static boolean isCPURegister(Register r) {
        return r.getRegisterCategory().equals(CPU);
    }

    public static boolean isGlobalRegister(Register r) {
        return isCPURegister(r) && g0.number <= r.number && r.number <= g7.number;
    }

    public static boolean isSingleFloatRegister(Register r) {
        return r.getRegisterCategory().equals(FPUs);
    }

    public static boolean isDoubleFloatRegister(Register r) {
        return r.getRegisterCategory().equals(FPUd);
    }

    public boolean hasFeature(CPUFeature feature) {
        return ((SPARC) this.target.arch).features.contains(feature);
    }

    public static final int simm(int x, int nbits) {
        // assert_signed_range(x, nbits);
        return x & ((1 << nbits) - 1);
    }

    public static final boolean isImm(int x, int nbits) {
        // assert_signed_range(x, nbits);
        return simm(x, nbits) == x;
    }

    /**
     * Minimum value for signed immediate ranges.
     */
    public static long minSimm(long nbits) {
        return -(1L << (nbits - 1));
    }

    /**
     * Maximum value for signed immediate ranges.
     */
    public static long maxSimm(long nbits) {
        return (1L << (nbits - 1)) - 1;
    }

    /**
     * Test if imm is within signed immediate range for nbits.
     */
    public static boolean isSimm(long imm, int nbits) {
        return minSimm(nbits) <= imm && imm <= maxSimm(nbits);
    }

    public static boolean isSimm10(long imm) {
        return isSimm(imm, 10);
    }

    public static boolean isSimm11(long imm) {
        return isSimm(imm, 11);
    }

    public static boolean isSimm11(JavaConstant constant) {
        return constant.isNull() || isSimm11(constant.asLong());
    }

    public static boolean isSimm5(JavaConstant constant) {
        return constant.isNull() || isSimm(constant.asLong(), 5);
    }

    public static boolean isSimm13(int imm) {
        return isSimm(imm, 13);
    }

    public static boolean isSimm13(JavaConstant constant) {
        long bits;
        switch (constant.getJavaKind()) {
            case Double:
                bits = Double.doubleToRawLongBits(constant.asDouble());
                break;
            case Float:
                bits = Float.floatToRawIntBits(constant.asFloat());
                break;
            case Object:
                return constant.isNull();
            default:
                bits = constant.asLong();
                break;
        }
        return constant.isNull() || isSimm13(bits);
    }

    public static boolean isSimm13(long imm) {
        return NumUtil.isInt(imm) && isSimm(imm, 13);
    }

    public static boolean isWordDisp30(long imm) {
        return isSimm(imm, 30 + 2);
    }

    public static final int hi22(int x) {
        return x >>> 10;
    }

    public static final int lo10(int x) {
        return x & ((1 << 10) - 1);
    }

    // @formatter:off
    /**
     * Instruction format for Fmt00 instructions. This abstraction is needed as it
     * makes the patching easier later on.
     * <pre>
     * | 00  |    a   | op2 |               b                         |
     * |31 30|29    25|24 22|21                                      0|
     * </pre>
     */
    // @formatter:on
    protected void fmt00(int a, int op2, int b) {
        assert isImm(a, 5) && isImm(op2, 3) && isImm(b, 22) : String.format("a: 0x%x op2: 0x%x b: 0x%x", a, op2, b);
        int word = 0;
        BitSpec.op.setBits(word, 0);
        BitSpec.rd.setBits(word, a);
        BitSpec.op2.setBits(word, op2);
        BitSpec.imm22.setBits(word, b);
        emitInt(a << 25 | op2 << 22 | b);
    }

    private void op3(Op3s op3, Opfs opf, Register rs1, Register rs2, Register rd) {
        int b = opf.value << 5 | (rs2 == null ? 0 : rs2.encoding);
        fmt(op3.op.value, rd.encoding, op3.value, rs1 == null ? 0 : rs1.encoding, b);
    }

    protected void op3(Op3s op3, Register rs1, Register rs2, Register rd) {
        int b = rs2 == null ? 0 : rs2.encoding;
        int xBit = getXBit(op3);
        fmt(op3.op.value, rd.encoding, op3.value, rs1 == null ? 0 : rs1.encoding, b | xBit);
    }

    protected void op3(Op3s op3, Register rs1, int simm13, Register rd) {
        assert isSimm13(simm13) : simm13;
        int i = 1 << 13;
        int simm13WithX = simm13 | getXBit(op3);
        fmt(op3.op.value, rd.encoding, op3.value, rs1.encoding, i | simm13WithX & ((1 << 13) - 1));
    }

    public void insertNopAfterCBCond() {
        int pos = position() - INSTRUCTION_SIZE;
        if (pos == 0) {
            return;
        }
        int inst = getInt(pos);
        if (CBCOND.match(inst)) {
            nop();
        }
    }

    protected int patchUnbound(Label label) {
        label.addPatchAt(position());
        return 0;
    }

    // @formatter:off
    /**
     * NOP.
     * <pre>
     * | 00  |00000| 100 |                0                    |
     * |31 30|29 25|24 22|21                                  0|
     * </pre>
     */
    // @formatter:on
    public void nop() {
        emitInt(1 << 24);
    }

    public void sethi(int imm22, Register dst) {
        fmt00(dst.encoding, Op2s.Sethi.value, imm22);
    }

    // @formatter:off
    /**
     * Instruction format for calls.
     * <pre>
     * | 01  |                      disp30                             |
     * |31 30|29                                                      0|
     * </pre>
     *
     * @return Position of the call instruction
     */
    // @formatter:on
    public int call(int disp30) {
        assert isImm(disp30, 30);
        insertNopAfterCBCond();
        int before = position();
        int instr = 1 << 30;
        instr |= disp30;
        emitInt(instr);
        return before;
    }

    public void add(Register rs1, Register rs2, Register rd) {
        op3(Add, rs1, rs2, rd);
    }

    public void add(Register rs1, int simm13, Register rd) {
        op3(Add, rs1, simm13, rd);
    }

    public void addc(Register rs1, Register rs2, Register rd) {
        op3(Addc, rs1, rs2, rd);
    }

    public void addc(Register rs1, int simm13, Register rd) {
        op3(Addc, rs1, simm13, rd);
    }

    public void addcc(Register rs1, Register rs2, Register rd) {
        op3(Addcc, rs1, rs2, rd);
    }

    public void addcc(Register rs1, int simm13, Register rd) {
        op3(Addcc, rs1, simm13, rd);
    }

    public void and(Register rs1, Register rs2, Register rd) {
        op3(And, rs1, rs2, rd);
    }

    public void and(Register rs1, int simm13, Register rd) {
        op3(And, rs1, simm13, rd);
    }

    public void andcc(Register rs1, Register rs2, Register rd) {
        op3(Andcc, rs1, rs2, rd);
    }

    public void andcc(Register rs1, int simm13, Register rd) {
        op3(Andcc, rs1, simm13, rd);
    }

    public void andn(Register rs1, Register rs2, Register rd) {
        op3(Andn, rs1, rs2, rd);
    }

    public void andn(Register rs1, int simm13, Register rd) {
        op3(Andn, rs1, simm13, rd);
    }

    public void andncc(Register rs1, Register rs2, Register rd) {
        op3(Andncc, rs1, rs2, rd);
    }

    public void andncc(Register rs1, int simm13, Register rd) {
        op3(Andncc, rs1, simm13, rd);
    }

    public void movwtos(Register rs2, Register rd) {
        assert isSingleFloatRegister(rd) && isCPURegister(rs2) : String.format("%s %s", rs2, rd);
        op3(Impdep1, Movwtos, null, rs2, rd);
    }

    public void umulxhi(Register rs1, Register rs2, Register rd) {
        op3(Impdep1, UMulxhi, rs1, rs2, rd);
    }

    public void fdtos(Register rs2, Register rd) {
        assert isSingleFloatRegister(rd) && isDoubleFloatRegister(rs2) : String.format("%s %s", rs2, rd);
        op3(Fpop1, Fdtos, null, rs2, rd);
    }

    public void movstouw(Register rs2, Register rd) {
        assert isSingleFloatRegister(rs2) && isCPURegister(rd) : String.format("%s %s", rs2, rd);
        op3(Impdep1, Movstosw, null, rs2, rd);
    }

    public void movstosw(Register rs2, Register rd) {
        assert isSingleFloatRegister(rs2) && isCPURegister(rd) : String.format("%s %s", rs2, rd);
        op3(Impdep1, Movstosw, null, rs2, rd);
    }

    public void movdtox(Register rs2, Register rd) {
        assert isDoubleFloatRegister(rs2) && isCPURegister(rd) : String.format("%s %s", rs2, rd);
        op3(Impdep1, Movdtox, null, rs2, rd);
    }

    public void movxtod(Register rs2, Register rd) {
        assert isCPURegister(rs2) && isDoubleFloatRegister(rd) : String.format("%s %s", rs2, rd);
        op3(Impdep1, Movxtod, null, rs2, rd);
    }

    public void fadds(Register rs1, Register rs2, Register rd) {
        op3(Fpop1, Fadds, rs1, rs2, rd);
    }

    public void faddd(Register rs1, Register rs2, Register rd) {
        op3(Fpop1, Faddd, rs1, rs2, rd);
    }

    public void fdivs(Register rs1, Register rs2, Register rd) {
        op3(Fpop1, Fdivs, rs1, rs2, rd);
    }

    public void fdivd(Register rs1, Register rs2, Register rd) {
        op3(Fpop1, Fdivd, rs1, rs2, rd);
    }

    public void fmovs(Register rs2, Register rd) {
        op3(Fpop1, Fmovs, null, rs2, rd);
    }

    public void fmovd(Register rs2, Register rd) {
        op3(Fpop1, Fmovd, null, rs2, rd);
    }

    public void fsrc2s(Register rs2, Register rd) {
        op3(Impdep1, Fsrc2s, null, rs2, rd);
    }

    public void fsrc2d(Register rs2, Register rd) {
        op3(Impdep1, Fsrc2d, null, rs2, rd);
    }

    public void fmuls(Register rs1, Register rs2, Register rd) {
        op3(Fpop1, Fmuls, rs1, rs2, rd);
    }

    public void fsmuld(Register rs1, Register rs2, Register rd) {
        op3(Fpop1, Fsmuld, rs1, rs2, rd);
    }

    public void fmuld(Register rs1, Register rs2, Register rd) {
        op3(Fpop1, Fmuld, rs1, rs2, rd);
    }

    public void fnegs(Register rs2, Register rd) {
        op3(Fpop1, Fnegs, null, rs2, rd);
    }

    public void fnegd(Register rs2, Register rd) {
        op3(Fpop1, Fnegd, null, rs2, rd);
    }

    /**
     * Helper method to determine if the instruction needs the X bit set.
     */
    private static int getXBit(Op3s op3) {
        switch (op3) {
            case Sllx:
            case Srax:
            case Srlx:
                return 1 << 12;
            default:
                return 0;
        }
    }

    public void fstoi(Register rs2, Register rd) {
        op3(Fpop1, Fstoi, null, rs2, rd);
    }

    public void fstox(Register rs2, Register rd) {
        op3(Fpop1, Fstox, null, rs2, rd);
    }

    public void fdtox(Register rs2, Register rd) {
        op3(Fpop1, Fdtox, null, rs2, rd);
    }

    public void fstod(Register rs2, Register rd) {
        op3(Fpop1, Fstod, null, rs2, rd);
    }

    public void fdtoi(Register rs2, Register rd) {
        op3(Fpop1, Fdtoi, null, rs2, rd);
    }

    public void fitos(Register rs2, Register rd) {
        op3(Fpop1, Fitos, null, rs2, rd);
    }

    public void fitod(Register rs2, Register rd) {
        op3(Fpop1, Fitod, null, rs2, rd);
    }

    public void fxtos(Register rs2, Register rd) {
        op3(Fpop1, Fxtos, null, rs2, rd);
    }

    public void fxtod(Register rs2, Register rd) {
        op3(Fpop1, Fxtod, null, rs2, rd);
    }

    public void fzeros(Register rd) {
        op3(Impdep1, Fzeros, null, null, rd);
    }

    public void fzerod(Register rd) {
        op3(Impdep1, Fzerod, null, null, rd);
    }

    public void flushw() {
        op3(Flushw, g0, g0, g0);
    }

    public void fsqrtd(Register rs2, Register rd) {
        op3(Fpop1, Fsqrtd, null, rs2, rd);
    }

    public void fsqrts(Register rs2, Register rd) {
        op3(Fpop1, Fsqrts, null, rs2, rd);
    }

    public void fabss(Register rs2, Register rd) {
        op3(Fpop1, Fabss, null, rs2, rd);
    }

    public void fabsd(Register rs2, Register rd) {
        op3(Fpop1, Fabsd, null, rs2, rd);
    }

    public void fsubs(Register rs1, Register rs2, Register rd) {
        op3(Fpop1, Fsubs, rs1, rs2, rd);
    }

    public void fsubd(Register rs1, Register rs2, Register rd) {
        op3(Fpop1, Fsubd, rs1, rs2, rd);
    }

    // @formatter:off
    /**
     * Instruction format for fcmp.
     * <pre>
     * | 10  | --- |cc1|cc0|desc |   rs1   |   opf  | rs2 |
     * |31 30|29 27|26 |25 |24 19|18     14|13     5|4   0|
     * </pre>
     */
    // @formatter:on
    public void fcmp(CC cc, Opfs opf, Register rs1, Register rs2) {
        int a = cc.value;
        int b = opf.value << 5 | rs2.encoding;
        delaySlotOptimizationPoints.add(position());
        fmt10(a, Fpop2.value, rs1.encoding, b);
    }

    // @formatter:off
    /**
     * Instruction format for most arithmetic stuff.
     * <pre>
     * |  10 | rd  | op3 | rs1 |   b   |
     * |31 30|29 25|24 19|18 14|13    0|
     * </pre>
     */
    // @formatter:on
    protected void fmt10(int rd, int op3, int rs1, int b) {
        fmt(0b10, rd, op3, rs1, b);
    }

    // @formatter:off
    /**
     * Instruction format for most arithmetic stuff.
     * <pre>
     * |  op | rd  | op3 | rs1 |   b   |
     * |31 30|29 25|24 19|18 14|13    0|
     * </pre>
     */
    // @formatter:on
    protected void fmt(int op, int rd, int op3, int rs1, int b) {
        assert isImm(rd, 5) && isImm(op3, 6) && isImm(b, 14) : String.format("rd: 0x%x op3: 0x%x b: 0x%x", rd, op3, b);
        int instr = op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | b;
        emitInt(instr);
    }

    public void illtrap(int const22) {
        fmt00(0, Op2s.Illtrap.value, const22);
    }

    public void jmpl(Register rs1, Register rs2, Register rd) {
        insertNopAfterCBCond();
        op3(Jmpl, rs1, rs2, rd);
    }

    /**
     * @return Position of the jmpl instruction
     */
    public int jmpl(Register rs1, int simm13, Register rd) {
        insertNopAfterCBCond();
        int before = position();
        op3(Jmpl, rs1, simm13, rd);
        return before;
    }

    public void fmovdcc(ConditionFlag cond, CC cc, Register rs2, Register rd) {
        fmovcc(cond, cc, rs2, rd, OpfLow.Fmovdcc.value);
    }

    public void fmovscc(ConditionFlag cond, CC cc, Register rs2, Register rd) {
        fmovcc(cond, cc, rs2, rd, OpfLow.Fmovscc.value);
    }

    private void fmovcc(ConditionFlag cond, CC cc, Register rs2, Register rd, int opfLow) {
        int opfCC = cc.value;
        int a = opfCC << 11 | opfLow << 5 | rs2.encoding;
        fmt10(rd.encoding, Fpop2.value, cond.value, a);
    }

    public void movcc(ConditionFlag conditionFlag, CC cc, Register rs2, Register rd) {
        movcc(conditionFlag, cc, 0, rs2.encoding, rd);
    }

    public void movcc(ConditionFlag conditionFlag, CC cc, int simm11, Register rd) {
        assert isSimm11(simm11);
        movcc(conditionFlag, cc, 1, simm11 & ((1 << 11) - 1), rd);
    }

    private void movcc(ConditionFlag conditionFlag, CC cc, int i, int imm, Register rd) {
        int cc01 = 0b11 & cc.value;
        int cc2 = cc.isFloat ? 0 : 1;
        int a = cc2 << 4 | conditionFlag.value;
        int b = cc01 << 11 | i << 13 | imm;
        fmt10(rd.encoding, Movcc.value, a, b);
    }

    public void mulx(Register rs1, Register rs2, Register rd) {
        op3(Mulx, rs1, rs2, rd);
    }

    public void mulx(Register rs1, int simm13, Register rd) {
        op3(Mulx, rs1, simm13, rd);
    }

    public void or(Register rs1, Register rs2, Register rd) {
        assert isCPURegister(rs1, rs2, rd) : String.format("%s %s %s", rs1, rs2, rd);
        op3(Or, rs1, rs2, rd);
    }

    public void or(Register rs1, int simm13, Register rd) {
        assert isCPURegister(rs1, rd) : String.format("%s %s", rs1, rd);
        op3(Or, rs1, simm13, rd);
    }

    public void popc(Register rs2, Register rd) {
        op3(Popc, g0, rs2, rd);
    }

    public void popc(int simm13, Register rd) {
        op3(Popc, g0, simm13, rd);
    }

    public void prefetch(SPARCAddress addr, Fcn fcn) {
        Register rs1 = addr.getBase();
        if (addr.getIndex().equals(Register.None)) {
            int dis = addr.getDisplacement();
            assert isSimm13(dis);
            fmt(Prefetch.op.value, fcn.value, Prefetch.value, rs1.encoding, 1 << 13 | dis & ((1 << 13) - 1));
        } else {
            Register rs2 = addr.getIndex();
            fmt(Prefetch.op.value, fcn.value, Prefetch.value, rs1.encoding, rs2.encoding);
        }
    }

    // A.44 Read State Register

    public void rdpc(Register rd) {
        op3(Rd, g5, g0, rd);
    }

    public void restore(Register rs1, Register rs2, Register rd) {
        op3(Restore, rs1, rs2, rd);
    }

    public static final int PC_RETURN_OFFSET = 8;

    public void save(Register rs1, Register rs2, Register rd) {
        op3(Save, rs1, rs2, rd);
    }

    public void save(Register rs1, int simm13, Register rd) {
        op3(Save, rs1, simm13, rd);
    }

    public void sdivx(Register rs1, Register rs2, Register rd) {
        op3(Sdivx, rs1, rs2, rd);
    }

    public void sdivx(Register rs1, int simm13, Register rd) {
        op3(Sdivx, rs1, simm13, rd);
    }

    public void udivx(Register rs1, Register rs2, Register rd) {
        op3(Udivx, rs1, rs2, rd);
    }

    public void udivx(Register rs1, int simm13, Register rd) {
        op3(Udivx, rs1, simm13, rd);
    }

    public void sll(Register rs1, Register rs2, Register rd) {
        op3(Sll, rs1, rs2, rd);
    }

    public void sll(Register rs1, int shcnt32, Register rd) {
        assert isImm(shcnt32, 5);
        op3(Sll, rs1, shcnt32, rd);
    }

    public void sllx(Register rs1, Register rs2, Register rd) {
        op3(Sllx, rs1, rs2, rd);
    }

    public void sllx(Register rs1, int shcnt64, Register rd) {
        assert isImm(shcnt64, 6);
        op3(Sllx, rs1, shcnt64, rd);
    }

    public void sra(Register rs1, Register rs2, Register rd) {
        op3(Sra, rs1, rs2, rd);
    }

    public void sra(Register rs1, int simm13, Register rd) {
        op3(Sra, rs1, simm13, rd);
    }

    public void srax(Register rs1, Register rs2, Register rd) {
        op3(Srax, rs1, rs2, rd);
    }

    public void srax(Register rs1, int shcnt64, Register rd) {
        assert isImm(shcnt64, 6);
        op3(Srax, rs1, shcnt64, rd);
    }

    public void srl(Register rs1, Register rs2, Register rd) {
        op3(Srl, rs1, rs2, rd);
    }

    public void srl(Register rs1, int simm13, Register rd) {
        op3(Srl, rs1, simm13, rd);
    }

    public void srlx(Register rs1, Register rs2, Register rd) {
        op3(Srlx, rs1, rs2, rd);
    }

    public void srlx(Register rs1, int shcnt64, Register rd) {
        assert isImm(shcnt64, 6);
        op3(Srlx, rs1, shcnt64, rd);
    }

    public void sub(Register rs1, Register rs2, Register rd) {
        op3(Sub, rs1, rs2, rd);
    }

    public void sub(Register rs1, int simm13, Register rd) {
        op3(Sub, rs1, simm13, rd);
    }

    public void subcc(Register rs1, Register rs2, Register rd) {
        op3(Subcc, rs1, rs2, rd);
    }

    public void subcc(Register rs1, int simm13, Register rd) {
        op3(Subcc, rs1, simm13, rd);
    }

    public void ta(int trap) {
        tcc(Icc, Always, trap);
    }

    public void pause() {
        // Maybe fmt10(rd=0b1_1011, op3=0b11_0000, rs1=0, i=1, simm13=1), or
        // maybe op3(Wr, g0, 1, %pause).
        // What should the count be?
        GraalError.unimplemented("The SPARC pause instruction is not yet implemented.");
    }

    public void tcc(CC cc, ConditionFlag flag, int trap) {
        assert isImm(trap, 8);
        int b = cc.value << 11;
        b |= 1 << 13;
        b |= trap;
        fmt10(flag.value, Op3s.Tcc.getValue(), 0, b);
    }

    public void wrccr(Register rs1, Register rs2) {
        op3(Wr, rs1, rs2, g2);
    }

    public void wrccr(Register rs1, int simm13) {
        op3(Wr, rs1, simm13, g2);
    }

    public void xor(Register rs1, Register rs2, Register rd) {
        op3(Xor, rs1, rs2, rd);
    }

    public void xor(Register rs1, int simm13, Register rd) {
        op3(Xor, rs1, simm13, rd);
    }

    public void xorcc(Register rs1, Register rs2, Register rd) {
        op3(Xorcc, rs1, rs2, rd);
    }

    public void xorcc(Register rs1, int simm13, Register rd) {
        op3(Xorcc, rs1, simm13, rd);
    }

    public void xnor(Register rs1, Register rs2, Register rd) {
        op3(Xnor, rs1, rs2, rd);
    }

    public void xnor(Register rs1, int simm13, Register rd) {
        op3(Xnor, rs1, simm13, rd);
    }

    /*
     * Load/Store
     */
    protected void ld(Op3s op3, SPARCAddress addr, Register rd, Asi asi) {
        Register rs1 = addr.getBase();
        if (!addr.getIndex().equals(Register.None)) {
            Register rs2 = addr.getIndex();
            if (asi != null) {
                int b = rs2.encoding;
                b |= asi.value << 5;
                fmt(op3.op.value, rd.encoding, op3.value, rs1.encoding, b);
            } else {
                op3(op3, rs1, rs2, rd);
            }
        } else {
            int imm = addr.getDisplacement();
            op3(op3, rs1, imm, rd);
        }
    }

    protected void ld(Op3s op3, SPARCAddress addr, Register rd) {
        ld(op3, addr, rd, null);
    }

    public void lddf(SPARCAddress src, Register dst) {
        assert isDoubleFloatRegister(dst) : dst;
        ld(Lddf, src, dst);
    }

    public void ldf(SPARCAddress src, Register dst) {
        assert isSingleFloatRegister(dst) : dst;
        ld(Ldf, src, dst);
    }

    public void lduh(SPARCAddress src, Register dst) {
        assert isCPURegister(dst) : dst;
        ld(Lduh, src, dst);
    }

    public void ldsh(SPARCAddress src, Register dst) {
        assert isCPURegister(dst) : dst;
        ld(Ldsh, src, dst);
    }

    public void ld(SPARCAddress src, Register dst, int bytes, boolean signExtend) {
        if (isCPURegister(dst)) {
            if (signExtend) {
                switch (bytes) {
                    case 1:
                        ld(Ldsb, src, dst);
                        break;
                    case 2:
                        ld(Ldsh, src, dst);
                        break;
                    case 4:
                        ld(Ldsw, src, dst);
                        break;
                    case 8:
                        ld(Ldx, src, dst);
                        break;
                    default:
                        throw new InternalError();
                }
            } else {
                switch (bytes) {
                    case 1:
                        ld(Ldub, src, dst);
                        break;
                    case 2:
                        ld(Lduh, src, dst);
                        break;
                    case 4:
                        ld(Lduw, src, dst);
                        break;
                    case 8:
                        ld(Ldx, src, dst);
                        break;
                    default:
                        throw new InternalError();
                }
            }
        } else if (isDoubleFloatRegister(dst) && bytes == 8) {
            assert !signExtend;
            ld(Lddf, src, dst);
        } else if (isSingleFloatRegister(dst) && bytes == 4) {
            assert !signExtend;
            ld(Ldf, src, dst);
        } else {
            throw new InternalError(String.format("src: %s dst: %s bytes: %d signExtend: %b", src, dst, bytes, signExtend));
        }
    }

    public void st(Register src, SPARCAddress dst, int bytes) {
        if (isCPURegister(src)) {
            switch (bytes) {
                case 1:
                    st(Stb, src, dst);
                    break;
                case 2:
                    st(Sth, src, dst);
                    break;
                case 4:
                    st(Stw, src, dst);
                    break;
                case 8:
                    st(Stx, src, dst);
                    break;
                default:
                    throw new InternalError(Integer.toString(bytes));
            }
        } else if (isDoubleFloatRegister(src) && bytes == 8) {
            st(Stdf, src, dst);
        } else if (isSingleFloatRegister(src) && bytes == 4) {
            st(Stf, src, dst);
        } else {
            throw new InternalError(String.format("src: %s dst: %s bytes: %d", src, dst, bytes));
        }
    }

    public void ldub(SPARCAddress src, Register dst) {
        assert isCPURegister(dst) : dst;
        ld(Ldub, src, dst);
    }

    public void ldsb(SPARCAddress src, Register dst) {
        assert isCPURegister(dst) : dst;
        ld(Ldsb, src, dst);
    }

    public void lduw(SPARCAddress src, Register dst) {
        assert isCPURegister(dst) : dst;
        ld(Lduw, src, dst);
    }

    public void ldsw(SPARCAddress src, Register dst) {
        assert isCPURegister(dst) : dst;
        ld(Ldsw, src, dst);
    }

    public void ldx(SPARCAddress src, Register dst) {
        assert isCPURegister(dst) : dst;
        ld(Ldx, src, dst);
    }

    public void ldxa(Register rs1, Register rs2, Register rd, Asi asi) {
        assert isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
        ld(Ldxa, new SPARCAddress(rs1, rs2), rd, asi);
    }

    public void lduwa(Register rs1, Register rs2, Register rd, Asi asi) {
        assert isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
        ld(Lduwa, new SPARCAddress(rs1, rs2), rd, asi);
    }

    public void stxa(Register rd, Register rs1, Register rs2, Asi asi) {
        assert isCPURegister(rs1, rs2, rd) : format("%s %s %s", rs1, rs2, rd);
        ld(Stxa, new SPARCAddress(rs1, rs2), rd, asi);
    }

    protected void st(Op3s op3, Register rs1, SPARCAddress dest) {
        ld(op3, dest, rs1);
    }

    public void stdf(Register rd, SPARCAddress addr) {
        assert isDoubleFloatRegister(rd) : rd;
        st(Stdf, rd, addr);
    }

    public void stf(Register rd, SPARCAddress addr) {
        assert isSingleFloatRegister(rd) : rd;
        st(Stf, rd, addr);
    }

    public void stb(Register rd, SPARCAddress addr) {
        assert isCPURegister(rd) : rd;
        st(Stb, rd, addr);
    }

    public void sth(Register rd, SPARCAddress addr) {
        assert isCPURegister(rd) : rd;
        st(Sth, rd, addr);
    }

    public void stw(Register rd, SPARCAddress addr) {
        assert isCPURegister(rd) : rd;
        st(Stw, rd, addr);
    }

    public void stx(Register rd, SPARCAddress addr) {
        assert isCPURegister(rd) : rd;
        st(Stx, rd, addr);
    }

    public void membar(int barriers) {
        op3(Membar, o7, barriers, g0);
    }

    public void casa(Register rs1, Register rs2, Register rd, Asi asi) {
        ld(Casa, new SPARCAddress(rs1, rs2), rd, asi);
    }

    public void casxa(Register rs1, Register rs2, Register rd, Asi asi) {
        ld(Casxa, new SPARCAddress(rs1, rs2), rd, asi);
    }

    @Override
    public InstructionCounter getInstructionCounter() {
        return new SPARCInstructionCounter(this);
    }

    public void patchAddImmediate(int position, int simm13) {
        int inst = getInt(position);
        assert SPARCAssembler.isSimm13(simm13) : simm13;
        assert (inst >>> 30) == 0b10 : String.format("0x%x", inst);
        assert ((inst >>> 18) & 0b11_1111) == 0 : String.format("0x%x", inst);
        assert (inst & (1 << 13)) != 0 : String.format("0x%x", inst);
        inst = inst & (~((1 << 13) - 1));
        inst |= simm13 & ((1 << 12) - 1);
        emitInt(inst, position);
    }

    public void fpadd32(Register rs1, Register rs2, Register rd) {
        op3(Impdep1, Fpadd32, rs1, rs2, rd);
    }

    /**
     * Does peephole optimization on code generated by this assembler. This method should be called
     * at the end of code generation.
     * <p>
     * It searches for conditional branch instructions which has nop in the delay slot then looks at
     * the instruction at branch target; if it is an arithmetic instruction, which does not throw an
     * exception (e.g. division), it pulls this instruction into the delay slot and increments the
     * displacement by 1.
     */
    public void peephole() {
        for (int i : delaySlotOptimizationPoints) {
            optimizeDelaySlot(i);
        }
    }

    /**
     * Optimizes branch instruction <i>b</t> which has a nop in the delay slot. It tries to stuff
     * the instruction at <i>b</i>s branch target into the delay slot of <i>b</i>, set the annul
     * flag and increments <i>b</i>s disp field by 1;
     * <p>
     * If <i>b</i>s branch target instruction is an unconditional branch <i>t</i>, then it tries to
     * put <i>t</i>s delayed instruction into the delay slot of <i>b</i> and add the <i>t</i>s disp
     * field to <i>b</i>s disp field.
     */
    private void optimizeDelaySlot(int i) {
        int delaySlotAbsolute = i + INSTRUCTION_SIZE;
        int nextInst = getInt(delaySlotAbsolute);
        SPARCOp nextOp = getSPARCOp(nextInst);
        if (nextOp instanceof Sethi && Sethi.isNop(nextInst)) {
            int inst = getInt(i);
            SPARCOp op = getSPARCOp(inst);
            if (op instanceof ControlTransferOp && ((ControlTransferOp) op).hasDelaySlot() && ((ControlTransferOp) op).isAnnulable(inst)) {
                ControlTransferOp ctOp = (ControlTransferOp) op;
                int disp = ctOp.getDisp(inst);
                int branchTargetAbsolute = i + disp * INSTRUCTION_SIZE;
                int branchTargetInst = getInt(branchTargetAbsolute);
                SPARCOp branchTargetOp = getSPARCOp(branchTargetInst);
                if (branchTargetOp instanceof Op3Op) {
                    Op3s op3 = ((Op3Op) branchTargetOp).getOp3(branchTargetInst);
                    if (!op3.throwsException()) {
                        inst = ctOp.setDisp(inst, disp + 1); // Increment the offset
                        inst = ctOp.setAnnul(inst, true);
                        emitInt(inst, i);
                        emitInt(branchTargetInst, delaySlotAbsolute);
                    }
                } else if (branchTargetOp instanceof ControlTransferOp && !((ControlTransferOp) branchTargetOp).isConditional(branchTargetInst)) {
                    // If branchtarget is a unconditional branch
                    ControlTransferOp branchTargetOpBranch = (ControlTransferOp) branchTargetOp;
                    int btDisp = branchTargetOpBranch.getDisp(branchTargetInst);
                    int newDisp = disp + btDisp;
                    if (ctOp.isValidDisp(newDisp)) { // Test if we don't exceed field size
                        int instAfter = ctOp.setDisp(inst, newDisp);
                        instAfter = ctOp.setAnnul(instAfter, true);
                        branchTargetInst = getInt(branchTargetAbsolute + INSTRUCTION_SIZE);
                        branchTargetOp = getSPARCOp(branchTargetInst);
                        if (branchTargetOp instanceof Op3Op && !((Op3Op) branchTargetOp).getOp3(branchTargetInst).throwsException()) {
                            emitInt(instAfter, i);
                            emitInt(branchTargetInst, delaySlotAbsolute);
                        }
                    }
                }
            }
        }
    }
}
