use of org.graalvm.compiler.asm.sparc.SPARCAddress in project graal by oracle.
the class SPARCMove method emitStore.
public static void emitStore(Value input, SPARCAddress address, PlatformKind kind, SPARCDelayedControlTransfer delayedControlTransfer, LIRFrameState state, CompilationResultBuilder crb, SPARCMacroAssembler masm) {
try (ScratchRegister sc = masm.getScratchRegister()) {
Register scratch = sc.getRegister();
SPARCAddress addr = generateSimm13OffsetLoad(address, masm, scratch);
delayedControlTransfer.emitControlTransfer(crb, masm);
if (state != null) {
crb.recordImplicitException(masm.position(), state);
}
int byteCount = kind.getSizeInBytes();
masm.st(asRegister(input), addr, byteCount);
}
}
use of org.graalvm.compiler.asm.sparc.SPARCAddress in project graal by oracle.
the class SPARCMove method loadFromConstantTable.
/**
* This method creates a load from the constant section. It automatically respects the different
* patterns used for small constant sections (<8k) and large constant sections (>=8k). The
* generated patterns by this method must be understood by
* CodeInstaller::pd_patch_DataSectionReference (jvmciCodeInstaller_sparc.cpp).
*
* @return the number of bytes loaded from the constant table
*/
public static int loadFromConstantTable(CompilationResultBuilder crb, SPARCMacroAssembler masm, Register constantTableBase, Constant input, Register dest, SPARCDelayedControlTransfer delaySlotInstruction) {
SPARCAddress address;
ScratchRegister scratch = null;
try {
Data data = crb.createDataItem(input);
int size = data.getSize();
if (masm.isImmediateConstantLoad()) {
address = new SPARCAddress(constantTableBase, 0);
// Make delayed only, when using immediate constant load.
delaySlotInstruction.emitControlTransfer(crb, masm);
crb.recordDataReferenceInCode(data, size);
} else {
scratch = masm.getScratchRegister();
Register sr = scratch.getRegister();
crb.recordDataReferenceInCode(data, size);
masm.sethix(0, sr, true);
address = new SPARCAddress(sr, 0);
}
masm.ld(address, dest, size, false);
return size;
} finally {
if (scratch != null) {
scratch.close();
}
}
}
use of org.graalvm.compiler.asm.sparc.SPARCAddress in project graal by oracle.
the class SPARCArrayEqualsOp method emitTailCompares.
/**
* Emits code to compare the remaining 1 to 4 bytes.
*/
private void emitTailCompares(SPARCMacroAssembler masm, Register result, Register array1, Register array2, Label trueLabel, Label falseLabel) {
Label compare2Bytes = new Label();
Label compare1Byte = new Label();
Register tempReg1 = asRegister(temp3);
Register tempReg2 = asRegister(temp4);
if (kind.getByteCount() <= 4) {
// Compare trailing 4 bytes, if any.
masm.compareBranch(result, 4, Less, Xcc, compare2Bytes, PREDICT_NOT_TAKEN, null);
masm.lduw(new SPARCAddress(array1, 0), tempReg1);
masm.lduw(new SPARCAddress(array2, 0), tempReg2);
masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_NOT_TAKEN, null);
if (kind.getByteCount() <= 2) {
// Move array pointers forward.
masm.add(array1, 4, array1);
masm.add(array2, 4, array2);
masm.sub(result, 4, result);
// Compare trailing 2 bytes, if any.
masm.bind(compare2Bytes);
masm.compareBranch(result, 2, Less, Xcc, compare1Byte, PREDICT_TAKEN, null);
masm.lduh(new SPARCAddress(array1, 0), tempReg1);
masm.lduh(new SPARCAddress(array2, 0), tempReg2);
masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_TAKEN, null);
// The one-byte tail compare is only required for boolean and byte arrays.
if (kind.getByteCount() <= 1) {
// Move array pointers forward before we compare the last trailing byte.
masm.add(array1, 2, array1);
masm.add(array2, 2, array2);
masm.sub(result, 2, result);
// Compare trailing byte, if any.
masm.bind(compare1Byte);
masm.compareBranch(result, 1, NotEqual, Xcc, trueLabel, PREDICT_TAKEN, null);
masm.ldub(new SPARCAddress(array1, 0), tempReg1);
masm.ldub(new SPARCAddress(array2, 0), tempReg2);
masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_TAKEN, null);
} else {
masm.bind(compare1Byte);
}
} else {
masm.bind(compare2Bytes);
}
}
}
use of org.graalvm.compiler.asm.sparc.SPARCAddress in project graal by oracle.
the class SPARCArrayEqualsOp method emit8ByteCompare.
/**
* Emits code that uses 8-byte vector compares.
*/
private void emit8ByteCompare(SPARCMacroAssembler masm, Register result, Register array1, Register array2, Register length, Label trueLabel, Label falseLabel) {
assert lengthValue.getPlatformKind().equals(SPARCKind.WORD);
Label loop = new Label();
Label compareTail = new Label();
Label compareTailCorrectVectorEnd = new Label();
Register tempReg1 = asRegister(temp4);
Register tempReg2 = asRegister(temp5);
masm.sra(length, 0, length);
// tail count (in bytes)
masm.and(result, VECTOR_SIZE - 1, result);
// vector count (in bytes)
masm.andcc(length, ~(VECTOR_SIZE - 1), length);
BPCC.emit(masm, Xcc, Equal, NOT_ANNUL, PREDICT_NOT_TAKEN, compareTail);
// Delay slot
masm.sub(length, VECTOR_SIZE, length);
masm.add(array1, length, array1);
masm.add(array2, length, array2);
masm.sub(g0, length, length);
// Compare the last element first
masm.ldx(new SPARCAddress(array1, 0), tempReg1);
masm.ldx(new SPARCAddress(array2, 0), tempReg2);
masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_NOT_TAKEN, null);
masm.compareBranch(length, 0, Equal, Xcc, compareTailCorrectVectorEnd, PREDICT_NOT_TAKEN, null);
// Load the first value from array 1 (Later done in back branch delay-slot)
masm.ldx(new SPARCAddress(array1, length), tempReg1);
masm.bind(loop);
masm.ldx(new SPARCAddress(array2, length), tempReg2);
masm.cmp(tempReg1, tempReg2);
BPCC.emit(masm, Xcc, NotEqual, NOT_ANNUL, PREDICT_NOT_TAKEN, falseLabel);
// Delay slot, not annul, add for next iteration
masm.addcc(length, VECTOR_SIZE, length);
// Annul, to prevent access past the array
BPCC.emit(masm, Xcc, NotEqual, ANNUL, PREDICT_TAKEN, loop);
// Load in delay slot
masm.ldx(new SPARCAddress(array1, length), tempReg1);
// Tail count zero, therefore we can go to the end
masm.compareBranch(result, 0, Equal, Xcc, trueLabel, PREDICT_TAKEN, null);
masm.bind(compareTailCorrectVectorEnd);
// Correct the array pointers
masm.add(array1, VECTOR_SIZE, array1);
masm.add(array2, VECTOR_SIZE, array2);
masm.bind(compareTail);
}
use of org.graalvm.compiler.asm.sparc.SPARCAddress in project graal by oracle.
the class SPARCByteSwapOp method emitCode.
@Override
public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
SPARCAddress addr = (SPARCAddress) crb.asAddress(tmpSlot);
SPARCMove.emitStore(input, addr, result.getPlatformKind(), SPARCDelayedControlTransfer.DUMMY, null, crb, masm);
if (addr.getIndex().equals(Register.None)) {
Register tempReg = ValueUtil.asRegister(tempIndex, XWORD);
masm.setx(addr.getDisplacement(), tempReg, false);
addr = new SPARCAddress(addr.getBase(), tempReg);
}
getDelayedControlTransfer().emitControlTransfer(crb, masm);
switch((SPARCKind) input.getPlatformKind()) {
case WORD:
masm.lduwa(addr.getBase(), addr.getIndex(), asRegister(result, WORD), Asi.ASI_PRIMARY_LITTLE);
break;
case XWORD:
masm.ldxa(addr.getBase(), addr.getIndex(), asRegister(result, XWORD), Asi.ASI_PRIMARY_LITTLE);
break;
default:
throw GraalError.shouldNotReachHere();
}
}
Aggregations