gt:         final Register src = asRegister(input);
context: /*
   * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  package com.oracle.graal.lir.sparc;
  
  import static com.oracle.graal.asm.sparc.SPARCAssembler.MEMBAR_STORE_LOAD;
  import static com.oracle.graal.asm.sparc.SPARCAssembler.isSimm13;
  import static com.oracle.graal.lir.LIRInstruction.OperandFlag.COMPOSITE;
  import static com.oracle.graal.lir.LIRInstruction.OperandFlag.HINT;
  import static com.oracle.graal.lir.LIRInstruction.OperandFlag.ILLEGAL;
  import static com.oracle.graal.lir.LIRInstruction.OperandFlag.REG;
  import static com.oracle.graal.lir.LIRInstruction.OperandFlag.STACK;
  import static com.oracle.graal.lir.LIRInstruction.OperandFlag.UNINITIALIZED;
  import static com.oracle.graal.lir.LIRValueUtil.asJavaConstant;
  import static com.oracle.graal.lir.LIRValueUtil.isJavaConstant;
  import static jdk.internal.jvmci.code.MemoryBarriers.STORE_LOAD;
  import static jdk.internal.jvmci.code.ValueUtil.asRegister;
  import static jdk.internal.jvmci.code.ValueUtil.asStackSlot;
  import static jdk.internal.jvmci.code.ValueUtil.isRegister;
  import static jdk.internal.jvmci.code.ValueUtil.isStackSlot;
  import static jdk.internal.jvmci.sparc.SPARC.g0;
  import static jdk.internal.jvmci.sparc.SPARCKind.DOUBLE;
  import static jdk.internal.jvmci.sparc.SPARCKind.DWORD;
  import static jdk.internal.jvmci.sparc.SPARCKind.SINGLE;
  import static jdk.internal.jvmci.sparc.SPARCKind.WORD;
  
  import java.util.Set;
  
  import jdk.internal.jvmci.code.Register;
  import jdk.internal.jvmci.code.StackSlot;
  import jdk.internal.jvmci.code.StackSlotValue;
  import jdk.internal.jvmci.common.JVMCIError;
  import jdk.internal.jvmci.meta.AllocatableValue;
  import jdk.internal.jvmci.meta.Constant;
  import jdk.internal.jvmci.meta.JavaConstant;
  import jdk.internal.jvmci.meta.LIRKind;
  import jdk.internal.jvmci.meta.PlatformKind;
  import jdk.internal.jvmci.meta.Value;
  import jdk.internal.jvmci.sparc.SPARC;
  import jdk.internal.jvmci.sparc.SPARC.CPUFeature;
  import jdk.internal.jvmci.sparc.SPARCKind;
  
  import com.oracle.graal.asm.sparc.SPARCAddress;
  import com.oracle.graal.asm.sparc.SPARCAssembler;
  import com.oracle.graal.asm.sparc.SPARCMacroAssembler;
  import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister;
  import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Sethix;
  import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
  import com.oracle.graal.lir.LIRFrameState;
  import com.oracle.graal.lir.LIRInstructionClass;
  import com.oracle.graal.lir.Opcode;
  import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
  import com.oracle.graal.lir.StandardOp.LoadConstantOp;
  import com.oracle.graal.lir.StandardOp.NullCheck;
  import com.oracle.graal.lir.StandardOp.ValueMoveOp;
  import com.oracle.graal.lir.asm.CompilationResultBuilder;
  
  public class SPARCMove {
  
      public static class LoadInlineConstant extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction, LoadConstantOp {
          public static final LIRInstructionClass<LoadInlineConstant> TYPE = LIRInstructionClass.create(LoadInlineConstant.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(1);
          private JavaConstant constant;
          @Def({REG, STACK}) AllocatableValue result;
  
          public LoadInlineConstant(JavaConstant constant, AllocatableValue result) {
              super(TYPE, SIZE);
              this.constant = constant;
              this.result = result;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              if (isRegister(result)) {
                  const2reg(crb, masm, result, g0, constant, getDelayedControlTransfer());
              } else if (isStackSlot(result)) {
                  StackSlot slot = asStackSlot(result);
                  const2stack(crb, masm, slot, g0, getDelayedControlTransfer(), constant);
              }
          }
  
          public Constant getConstant() {
              return constant;
          }
  
          public AllocatableValue getResult() {
              return result;
          }
      }
  
      public static class LoadConstantFromTable extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<LoadConstantFromTable> TYPE = LIRInstructionClass.create(LoadConstantFromTable.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(1, 8);
  
          private Constant constant;
          @Def({REG, STACK}) AllocatableValue result;
          @Use({REG}) private AllocatableValue constantTableBase;
  
          public LoadConstantFromTable(Constant constant, AllocatableValue constantTableBase, AllocatableValue result) {
              super(TYPE, SIZE);
              this.constant = constant;
              this.result = result;
              this.constantTableBase = constantTableBase;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              final int byteCount = result.getPlatformKind().getSizeInBytes();
              assert byteCount > 1 : "Byte values must not be loaded via constant table";
              final Runnable recordReference = () -> crb.recordDataReferenceInCode(constant, byteCount);
              Register baseRegister = asRegister(constantTableBase);
              if (isRegister(result)) {
                  Register resultRegister = asRegister(result);
                  loadFromConstantTable(crb, masm, byteCount, baseRegister, resultRegister, getDelayedControlTransfer(), recordReference);
              } else if (isStackSlot(result)) {
                  try (ScratchRegister scratch = masm.getScratchRegister()) {
                      Register scratchRegister = scratch.getRegister();
                      loadFromConstantTable(crb, masm, byteCount, baseRegister, scratchRegister, getDelayedControlTransfer(), recordReference);
                      StackSlot slot = asStackSlot(result);
                      reg2stack(crb, masm, slot, scratchRegister.asValue(), getDelayedControlTransfer());
                  }
              }
          }
      }
  
      @Opcode("MOVE")
      public static class Move extends SPARCLIRInstruction implements ValueMoveOp, SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<Move> TYPE = LIRInstructionClass.create(Move.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(8);
  
          @Def({REG, STACK, HINT}) protected AllocatableValue result;
          @Use({REG, STACK}) protected AllocatableValue input;
  
          public Move(AllocatableValue result, AllocatableValue input) {
              super(TYPE, SIZE);
              this.result = result;
              this.input = input;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              move(crb, masm, getResult(), getInput(), getDelayedControlTransfer());
          }
  
          @Override
          public AllocatableValue getInput() {
              return input;
          }
  
          @Override
          public AllocatableValue getResult() {
              return result;
          }
      }
  
      /**
       * Move between floating-point and general purpose register domain.
       */
      @Opcode("MOVE_FPGP")
      public static final class MoveFpGp extends SPARCLIRInstruction implements ValueMoveOp, SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<MoveFpGp> TYPE = LIRInstructionClass.create(MoveFpGp.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(2);
  
          @Def({REG}) protected AllocatableValue result;
          @Use({REG}) protected AllocatableValue input;
          @Use({STACK, ILLEGAL}) protected AllocatableValue temp;
  
          public MoveFpGp(AllocatableValue result, AllocatableValue input, AllocatableValue temp) {
              super(TYPE, SIZE);
              this.result = result;
              this.input = input;
              this.temp = temp;
          }
  
          public AllocatableValue getInput() {
              return input;
          }
  
          public AllocatableValue getResult() {
              return result;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              SPARCKind inputKind = (SPARCKind) input.getPlatformKind();
              SPARCKind resultKind = (SPARCKind) result.getPlatformKind();
              if (AllocatableValue.ILLEGAL.equals(temp)) {
                  moveDirect(crb, masm, inputKind, resultKind);
              } else {
                  moveViaStack(crb, masm, inputKind, resultKind);
              }
          }
  
          private void moveDirect(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCKind inputKind, SPARCKind resultKind) {
              getDelayedControlTransfer().emitControlTransfer(crb, masm);
              if (resultKind == SINGLE) {
                  if (inputKind == WORD) {
                      masm.movwtos(asRegister(input, WORD), asRegister(result, SINGLE));
                  } else {
                      throw JVMCIError.shouldNotReachHere("inputKind: " + inputKind);
                  }
              } else if (resultKind == DOUBLE) {
                  if (inputKind == WORD) {
                      masm.movxtod(asRegister(input, WORD), asRegister(result, DOUBLE));
                  } else {
                      masm.movxtod(asRegister(input, DWORD), asRegister(result, DOUBLE));
                  }
              } else if (inputKind == SINGLE) {
                  if (resultKind == WORD) {
                      masm.movstosw(asRegister(input, SINGLE), asRegister(result, WORD));
                  } else {
                      masm.movstouw(asRegister(input, SINGLE), asRegister(result, WORD));
                  }
              } else if (inputKind == DOUBLE) {
                  if (resultKind == DWORD) {
                      masm.movdtox(asRegister(input, DOUBLE), asRegister(result, DWORD));
                  } else {
                      throw JVMCIError.shouldNotReachHere();
                  }
              }
          }
  
          private void moveViaStack(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCKind inputKind, SPARCKind resultKind) {
              int resultKindSize = resultKind.getSizeInBytes();
              assert inputKind.getSizeInBytes() == resultKindSize;
              try (ScratchRegister sc = masm.getScratchRegister()) {
                  Register scratch = sc.getRegister();
                  SPARCAddress tempAddress = generateSimm13OffsetLoad((SPARCAddress) crb.asAddress(temp), masm, scratch);
                  masm.st(asRegister(input), tempAddress, resultKindSize);
                  getDelayedControlTransfer().emitControlTransfer(crb, masm);
                  masm.ld(tempAddress, asRegister(result), resultKindSize, false);
              }
          }
      }
  
      public abstract static class MemOp extends SPARCLIRInstruction implements ImplicitNullCheck {
          public static final LIRInstructionClass<MemOp> TYPE = LIRInstructionClass.create(MemOp.class);
  
          protected final PlatformKind kind;
          @Use({COMPOSITE}) protected SPARCAddressValue address;
          @State protected LIRFrameState state;
  
          public MemOp(LIRInstructionClass<? extends MemOp> c, SizeEstimate size, PlatformKind kind, SPARCAddressValue address, LIRFrameState state) {
              super(c, size);
              this.kind = kind;
              this.address = address;
              this.state = state;
          }
  
          protected abstract void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm);
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              emitMemAccess(crb, masm);
          }
  
          public boolean makeNullCheckFor(Value value, LIRFrameState nullCheckState, int implicitNullCheckLimit) {
              if (state == null && address.isValidImplicitNullCheckFor(value, implicitNullCheckLimit)) {
                  state = nullCheckState;
                  return true;
              }
              return false;
          }
      }
  
      public static final class LoadOp extends MemOp implements SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<LoadOp> TYPE = LIRInstructionClass.create(LoadOp.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(1);
  
          @Def({REG}) protected AllocatableValue result;
          protected boolean signExtend;
  
          public LoadOp(PlatformKind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state) {
              this(kind, result, address, state, false);
          }
  
          public LoadOp(PlatformKind kind, AllocatableValue result, SPARCAddressValue address, LIRFrameState state, boolean signExtend) {
              super(TYPE, SIZE, kind, address, state);
              this.result = result;
              this.signExtend = signExtend;
          }
  
          @Override
          public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              emitLoad(crb, masm, address.toAddress(), result, signExtend, kind, getDelayedControlTransfer(), state);
          }
      }
  
      public static final class LoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<LoadAddressOp> TYPE = LIRInstructionClass.create(LoadAddressOp.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(8);
  
          @Def({REG}) protected AllocatableValue result;
          @Use({COMPOSITE, UNINITIALIZED}) protected SPARCAddressValue addressValue;
  
          public LoadAddressOp(AllocatableValue result, SPARCAddressValue address) {
              super(TYPE, SIZE);
              this.result = result;
              this.addressValue = address;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              SPARCAddress address = addressValue.toAddress();
              loadEffectiveAddress(crb, masm, address, asRegister(result, DWORD), getDelayedControlTransfer());
          }
      }
  
      public static final class LoadDataAddressOp extends SPARCLIRInstruction {
          public static final LIRInstructionClass<LoadDataAddressOp> TYPE = LIRInstructionClass.create(LoadDataAddressOp.class);
  
          @Def({REG}) protected AllocatableValue result;
          private final byte[] data;
  
          public LoadDataAddressOp(AllocatableValue result, byte[] data) {
              super(TYPE);
              this.result = result;
              this.data = data;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(data, 8);
              assert addr == masm.getPlaceholder();
              final boolean forceRelocatable = true;
              Register dstReg = asRegister(result);
              new Setx(0, dstReg, forceRelocatable).emit(masm);
          }
  
          @Override
          public SizeEstimate estimateSize() {
              return SizeEstimate.create(8, data.length);
          }
      }
  
      public static final class MembarOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<MembarOp> TYPE = LIRInstructionClass.create(MembarOp.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(1);
  
          private final int barriers;
  
          public MembarOp(final int barriers) {
              super(TYPE, SIZE);
              this.barriers = barriers;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              getDelayedControlTransfer().emitControlTransfer(crb, masm);
              masm.membar(MEMBAR_STORE_LOAD);
          }
  
          @Override
          public void verify() {
              assert barriers == STORE_LOAD : String.format("Got barriers 0x%x; On SPARC only STORE_LOAD barriers are accepted; all other barriers are not neccessary due to TSO", barriers);
          }
      }
  
      public static final class NullCheckOp extends SPARCLIRInstruction implements NullCheck, SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<NullCheckOp> TYPE = LIRInstructionClass.create(NullCheckOp.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(1);
  
          @Use({COMPOSITE}) protected SPARCAddressValue input;
          @State protected LIRFrameState state;
  
          public NullCheckOp(SPARCAddressValue input, LIRFrameState state) {
              super(TYPE, SIZE);
              this.input = input;
              this.state = state;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              getDelayedControlTransfer().emitControlTransfer(crb, masm);
              SPARCAddress addr = input.toAddress();
              crb.recordImplicitException(masm.position(), state);
              // Just need to check whether this is a valid address or not; alignment is not
              // checked
              masm.ldub(addr, g0);
          }
  
          public Value getCheckedValue() {
              return input;
          }
  
          public LIRFrameState getState() {
              return state;
          }
      }
  
      @Opcode("CAS")
      public static final class CompareAndSwapOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<CompareAndSwapOp> TYPE = LIRInstructionClass.create(CompareAndSwapOp.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(2);
  
          @Def({REG, HINT}) protected AllocatableValue result;
          @Alive({REG}) protected AllocatableValue address;
          @Alive({REG}) protected AllocatableValue cmpValue;
          @Use({REG}) protected AllocatableValue newValue;
  
          public CompareAndSwapOp(AllocatableValue result, AllocatableValue address, AllocatableValue cmpValue, AllocatableValue newValue) {
              super(TYPE, SIZE);
              this.result = result;
              this.address = address;
              this.cmpValue = cmpValue;
              this.newValue = newValue;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              move(crb, masm, result, newValue, SPARCDelayedControlTransfer.DUMMY);
              compareAndSwap(crb, masm, address, cmpValue, result, getDelayedControlTransfer());
          }
      }
  
      public static final class StackLoadAddressOp extends SPARCLIRInstruction implements SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<StackLoadAddressOp> TYPE = LIRInstructionClass.create(StackLoadAddressOp.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(2);
  
          @Def({REG}) protected AllocatableValue result;
          @Use({STACK, UNINITIALIZED}) protected StackSlotValue slot;
  
          public StackLoadAddressOp(AllocatableValue result, StackSlotValue address) {
              super(TYPE, SIZE);
              this.result = result;
              this.slot = address;
          }
  
          @Override
          public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              SPARCAddress address = (SPARCAddress) crb.asAddress(slot);
              loadEffectiveAddress(crb, masm, address, asRegister(result, DWORD), getDelayedControlTransfer());
          }
      }
  
      private static void loadEffectiveAddress(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCAddress address, Register result, SPARCDelayedControlTransfer delaySlotHolder) {
          if (address.getIndex().equals(Register.None)) {
              if (isSimm13(address.getDisplacement())) {
                  delaySlotHolder.emitControlTransfer(crb, masm);
                  masm.add(address.getBase(), address.getDisplacement(), result);
              } else {
                  assert result.encoding() != address.getBase().encoding();
                  new Setx(address.getDisplacement(), result).emit(masm);
                  // No relocation, therefore, the add can be delayed as well
                  delaySlotHolder.emitControlTransfer(crb, masm);
                  masm.add(address.getBase(), result, result);
              }
          } else {
              delaySlotHolder.emitControlTransfer(crb, masm);
              masm.add(address.getBase(), address.getIndex(), result);
          }
      }
  
      public static class StoreOp extends MemOp implements SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<StoreOp> TYPE = LIRInstructionClass.create(StoreOp.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(1);
  
          @Use({REG}) protected AllocatableValue input;
  
          public StoreOp(PlatformKind kind, SPARCAddressValue address, AllocatableValue input, LIRFrameState state) {
              super(TYPE, SIZE, kind, address, state);
              this.input = input;
          }
  
          @Override
          public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              emitStore(input, address.toAddress(), kind, getDelayedControlTransfer(), state, crb, masm);
          }
      }
  
      public static final class StoreConstantOp extends MemOp implements SPARCTailDelayedLIRInstruction {
          public static final LIRInstructionClass<StoreConstantOp> TYPE = LIRInstructionClass.create(StoreConstantOp.class);
          public static final SizeEstimate SIZE = SizeEstimate.create(2);
  
          protected final JavaConstant input;
  
          public StoreConstantOp(PlatformKind kind, SPARCAddressValue address, JavaConstant input, LIRFrameState state) {
              super(TYPE, SIZE, kind, address, state);
              this.input = input;
              if (!input.isDefaultForKind()) {
                  throw JVMCIError.shouldNotReachHere("Can only store null constants to memory");
              }
          }
  
          @Override
          public void emitMemAccess(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
              try (ScratchRegister sc = masm.getScratchRegister()) {
                  Register scratch = sc.getRegister();
                  SPARCAddress addr = generateSimm13OffsetLoad(address.toAddress(), masm, scratch);
                  getDelayedControlTransfer().emitControlTransfer(crb, masm);
                  if (state != null) {
                      crb.recordImplicitException(masm.position(), state);
                  }
                  int byteCount = kind.getSizeInBytes();
                  masm.st(g0, addr, byteCount);
              }
          }
      }
  
      public static void move(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
          move(crb, masm, result, g0, input, delaySlotLir);
      }
  
      public static void move(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Register constantTableBase, Value input, SPARCDelayedControlTransfer delaySlotLir) {
          if (isRegister(input)) {
              if (isRegister(result)) {
                  reg2reg(crb, masm, result, input, delaySlotLir);
              } else if (isStackSlot(result)) {
                  reg2stack(crb, masm, result, input, delaySlotLir);
              } else {
                  throw JVMCIError.shouldNotReachHere("Result is a: " + result);
              }
          } else if (isStackSlot(input)) {
              if (isRegister(result)) {
                  SPARCAddress inputAddress = (SPARCAddress) crb.asAddress(input);
                  emitLoad(crb, masm, inputAddress, result, false, input.getPlatformKind(), delaySlotLir, null);
              } else if (isStackSlot(result)) {
                  stack2stack(crb, masm, result, input, delaySlotLir);
              } else {
                  throw JVMCIError.shouldNotReachHere("Result is a: " + result);
              }
          } else if (isJavaConstant(input)) {
              JavaConstant constant = asJavaConstant(input);
              if (isRegister(result)) {
                  const2reg(crb, masm, result, constantTableBase, constant, delaySlotLir);
              } else if (isStackSlot(result)) {
                  const2stack(crb, masm, result, constantTableBase, delaySlotLir, constant);
              } else {
                  throw JVMCIError.shouldNotReachHere("Result is a: " + result);
              }
          } else {
              throw JVMCIError.shouldNotReachHere();
          }
      }
  
      public static void const2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Register constantTableBase, SPARCDelayedControlTransfer delaySlotLir, JavaConstant constant) {
          if (constant.isDefaultForKind() || constant.isNull()) {
              SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
              emitStore(g0.asValue(LIRKind.combine(result)), resultAddress, result.getPlatformKind(), delaySlotLir, null, crb, masm);
          } else {
              try (ScratchRegister sc = masm.getScratchRegister()) {
                  Value scratchRegisterValue = sc.getRegister().asValue(LIRKind.combine(result));
                  const2reg(crb, masm, scratchRegisterValue, constantTableBase, constant, SPARCDelayedControlTransfer.DUMMY);
                  SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
                  emitStore(scratchRegisterValue, resultAddress, result.getPlatformKind(), delaySlotLir, null, crb, masm);
              }
          }
      }
  
      public static void stack2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, PlatformKind resultKind, PlatformKind inputKind, Value result, Value input,
                      SPARCDelayedControlTransfer delaySlotLir) {
          try (ScratchRegister sc = masm.getScratchRegister()) {
              SPARCAddress inputAddress = (SPARCAddress) crb.asAddress(input);
              Value scratchRegisterValue = sc.getRegister().asValue(LIRKind.combine(input));
              emitLoad(crb, masm, inputAddress, scratchRegisterValue, false, inputKind, SPARCDelayedControlTransfer.DUMMY, null);
              SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
              emitStore(scratchRegisterValue, resultAddress, resultKind, delaySlotLir, null, crb, masm);
          }
      }
  
      public static void stack2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
          stack2stack(crb, masm, result.getPlatformKind(), input.getPlatformKind(), result, input, delaySlotLir);
      }
  
      public static void reg2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
          SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
          emitStore(input, resultAddress, result.getPlatformKind(), delaySlotLir, null, crb, masm);
      }
  
      public static void reg2reg(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Value input, SPARCDelayedControlTransfer delaySlotLir) {
  