# HG changeset patch # User Stefan Anzinger # Date 1438946904 -7200 # Node ID 9961439fc100a8032b4d187404ff2692c213216c # Parent 24843a13b2afed1f9bd88caaf51464b18fb3148d [SPARC] Consolidate compareBranch into SPARCMacroAssembler diff -r 24843a13b2af -r 9961439fc100 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Thu Aug 06 16:05:23 2015 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Fri Aug 07 13:28:24 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -60,25 +60,6 @@ public static final int CCR_XCC_SHIFT = 4; public static final int CCR_V_SHIFT = 1; - protected static final int OP2_SHIFT = 22; - protected static final int OP2_MASK = 0b0000_0001_1100_0000_0000_0000_0000_0000; - - protected static final int DISP22_SHIFT = 0; - protected static final int DISP22_MASK = 0b00000000001111111111111111111111; - - protected static final int DISP19_SHIFT = 0; - protected static final int DISP19_MASK = 0b00000000000001111111111111111111; - - protected static final int D16HI_SHIFT = 20; - protected static final int D16HI_MASK = 0b0000_0000_0011_0000_0000_0000_0000_0000; - protected static final int D16LO_SHIFT = 0; - protected static final int D16LO_MASK = 0b0000_0000_0000_0000_0011_1111_1111_1111; - - protected static final int D10LO_MASK = 0b0000_0000_0000_0000_0001_1111_1110_0000; - protected static final int D10HI_MASK = 0b0000_0000_0001_1000_0000_0000_0000_0000; - protected static final int D10LO_SHIFT = 5; - protected static final int D10HI_SHIFT = 19; - private static final Ops[] OPS; private static final Op2s[] OP2S; private static final Op3s[][] OP3S; @@ -107,12 +88,10 @@ public enum Ops { // @formatter:off - BranchOp(0b00), CallOp(0b01), ArithOp(0b10), LdstOp(0b11); - // @formatter:on private final int value; @@ -133,7 +112,6 @@ public enum Op2s { // @formatter:off - Illtrap(0b000), Bpr (0b011), Fb (0b110), @@ -142,8 +120,6 @@ Bp (0b001), Cb (0b111), Sethi (0b100); - - // @formatter:on private final int value; @@ -956,7 +932,7 @@ } private int leftBits(int value) { - return SPARCAssembler.getBits(value, rightWidth + leftWidth, rightWidth); + return SPARCAssembler.getBits(value, rightWidth + leftWidth - 1, rightWidth); } private int rightBits(int value) { @@ -1304,12 +1280,14 @@ 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); 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); } @@ -1670,38 +1648,6 @@ return 0; } - public void cbcondw(ConditionFlag cf, Register rs1, Register rs2, Label lab) { - cbcond(0, 0, cf, rs1, rs2.encoding, lab); - } - - public void cbcondw(ConditionFlag cf, Register rs1, int rs2, Label lab) { - assert isSimm(rs2, 5); - cbcond(0, 1, cf, rs1, rs2 & ((1 << 5) - 1), lab); - } - - public void cbcondx(ConditionFlag cf, Register rs1, Register rs2, Label lab) { - cbcond(1, 0, cf, rs1, rs2.encoding, lab); - } - - public void cbcondx(ConditionFlag cf, Register rs1, int rs2, Label lab) { - assert isSimm(rs2, 5); - cbcond(1, 1, cf, rs1, rs2 & ((1 << 5) - 1), lab); - } - - private void cbcond(int cc2, int i, ConditionFlag cf, Register rs1, int rs2, Label l) { - insertNopAfterCBCond(); - int disp10 = !l.isBound() ? patchUnbound(l) : (l.position() - position()) / 4; - assert isSimm(disp10, 10) && isImm(rs2, 5); - disp10 &= (1 << 10) - 1; - final int cLo = cf.value & 0b111; - final int cHi = cf.value >> 3; - final int d10Lo = disp10 & ((1 << 8) - 1); - final int d10Hi = disp10 >> 8; - int a = cHi << 4 | 0b1000 | cLo; - int b = cc2 << 21 | d10Hi << D10HI_SHIFT | rs1.encoding << 14 | i << 13 | d10Lo << D10LO_SHIFT | rs2; - fmt00(a, Op2s.Bpr.value, b); - } - // @formatter:off /** * NOP. diff -r 24843a13b2af -r 9961439fc100 graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Thu Aug 06 16:05:23 2015 +0200 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCMacroAssembler.java Fri Aug 07 13:28:24 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,12 +23,17 @@ package com.oracle.graal.asm.sparc; import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; +import static com.oracle.graal.asm.sparc.SPARCAssembler.RCondition.*; import static jdk.internal.jvmci.sparc.SPARC.*; import java.util.function.*; import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.sparc.*; +import jdk.internal.jvmci.sparc.SPARC.CPUFeature; import com.oracle.graal.asm.*; @@ -389,4 +394,56 @@ nextFreeScratchRegister--; } } + + public void compareBranch(Register rs1, Register rs2, ConditionFlag cond, CC ccRegister, Label label, BranchPredict predict, Runnable delaySlotInstruction) { + assert isCPURegister(rs1, rs2); + assert ccRegister == Icc || ccRegister == Xcc; + if (hasFeature(CPUFeature.CBCOND)) { + if (delaySlotInstruction != null) { + delaySlotInstruction.run(); + } + CBCOND.emit(this, cond, ccRegister == Xcc, rs1, rs2, label); + } else { + if (cond == Equal && rs1.equals(g0)) { + bpr(Rc_z, NOT_ANNUL, label, PREDICT_NOT_TAKEN, rs1); + } else { + cmp(rs1, rs2); + bpcc(cond, NOT_ANNUL, label, ccRegister, predict); + } + if (delaySlotInstruction != null) { + int positionBefore = position(); + delaySlotInstruction.run(); + int positionAfter = position(); + assert positionBefore - positionAfter > SPARC.INSTRUCTION_SIZE : "Emitted more than one instruction into delay slot"; + } else { + nop(); + } + } + } + + public void compareBranch(Register rs1, int simm, ConditionFlag cond, CC ccRegister, Label label, BranchPredict predict, Runnable delaySlotInstruction) { + assert isCPURegister(rs1); + assert ccRegister == Icc || ccRegister == Xcc; + if (hasFeature(CPUFeature.CBCOND)) { + if (delaySlotInstruction != null) { + delaySlotInstruction.run(); + } + CBCOND.emit(this, cond, ccRegister == Xcc, rs1, simm, label); + } else { + if (cond == Equal && simm == 0) { + bpr(Rc_z, NOT_ANNUL, label, PREDICT_NOT_TAKEN, rs1); + } else { + cmp(rs1, simm); + bpcc(cond, NOT_ANNUL, label, ccRegister, predict); + } + if (delaySlotInstruction != null) { + int positionBefore = position(); + delaySlotInstruction.run(); + int positionAfter = position(); + assert positionBefore - positionAfter > SPARC.INSTRUCTION_SIZE : "Emitted more than one instruction into delay slot"; + } else { + nop(); + } + } + } } diff -r 24843a13b2af -r 9961439fc100 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Thu Aug 06 16:05:23 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Fri Aug 07 13:28:24 2015 +0200 @@ -414,15 +414,7 @@ Label noOverflow = new Label(); masm.sra(asIntReg(dst), 0, tmp); masm.xorcc(SPARC.g0, SPARC.g0, SPARC.g0); - if (masm.hasFeature(SPARC.CPUFeature.CBCOND)) { - masm.cbcondx(Equal, tmp, asIntReg(dst), noOverflow); - // Is necessary, otherwise we will have a penalty of 5 cycles in S3 - masm.nop(); - } else { - masm.cmp(tmp, asIntReg(dst)); - masm.bpcc(Equal, NOT_ANNUL, noOverflow, Xcc, PREDICT_TAKEN); - masm.nop(); - } + masm.compareBranch(tmp, asRegister(dst), Equal, Xcc, noOverflow, PREDICT_TAKEN, null); masm.wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT)); masm.bind(noOverflow); } diff -r 24843a13b2af -r 9961439fc100 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Thu Aug 06 16:05:23 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArrayEqualsOp.java Fri Aug 07 13:28:24 2015 +0200 @@ -26,18 +26,15 @@ import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; -import static com.oracle.graal.asm.sparc.SPARCAssembler.RCondition.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static jdk.internal.jvmci.code.ValueUtil.*; import static jdk.internal.jvmci.common.UnsafeAccess.*; import static jdk.internal.jvmci.sparc.SPARC.*; -import static jdk.internal.jvmci.sparc.SPARC.CPUFeature.*; import java.lang.reflect.*; import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.meta.*; -import jdk.internal.jvmci.sparc.SPARC.CPUFeature; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; @@ -143,8 +140,6 @@ Register tempReg1 = asRegister(temp4); Register tempReg2 = asRegister(temp5); - boolean hasCBcond = masm.hasFeature(CPUFeature.CBCOND); - masm.sra(length, 0, length); masm.and(result, VECTOR_SIZE - 1, result); // tail count (in bytes) masm.andcc(length, ~(VECTOR_SIZE - 1), length); // vector count (in bytes) @@ -158,16 +153,8 @@ // Compare the last element first masm.ldx(new SPARCAddress(array1, 0), tempReg1); masm.ldx(new SPARCAddress(array2, 0), tempReg2); - if (hasCBcond) { - masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel); - masm.cbcondx(Equal, length, 0, compareTailCorrectVectorEnd); - } else { - masm.cmp(tempReg1, tempReg2); - masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN); - masm.nop(); - masm.bpr(Rc_z, NOT_ANNUL, compareTailCorrectVectorEnd, PREDICT_NOT_TAKEN, length); - masm.nop(); - } + 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); @@ -182,12 +169,7 @@ masm.ldx(new SPARCAddress(array1, length), tempReg1); // Load in delay slot // Tail count zero, therefore we can go to the end - if (hasCBcond) { - masm.cbcondx(Equal, result, 0, trueLabel); - } else { - masm.bpr(Rc_z, NOT_ANNUL, trueLabel, PREDICT_TAKEN, result); - masm.nop(); - } + masm.compareBranch(result, 0, Equal, Xcc, trueLabel, PREDICT_TAKEN, null); masm.bind(compareTailCorrectVectorEnd); // Correct the array pointers @@ -206,28 +188,14 @@ Register tempReg1 = asRegister(temp3); Register tempReg2 = asRegister(temp4); - boolean hasCBcond = masm.hasFeature(CBCOND); if (kind.getByteCount() <= 4) { // Compare trailing 4 bytes, if any. - if (hasCBcond) { - masm.cbcondx(Less, result, 4, compare2Bytes); - } else { - masm.cmp(result, 4); - masm.bpcc(Less, NOT_ANNUL, compare2Bytes, Xcc, PREDICT_NOT_TAKEN); - masm.nop(); - } + 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); - - if (hasCBcond) { - masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel); - } else { - masm.cmp(tempReg1, tempReg2); - masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_NOT_TAKEN); - masm.nop(); - } + masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_NOT_TAKEN, null); if (kind.getByteCount() <= 2) { // Move array pointers forward. @@ -238,24 +206,12 @@ // Compare trailing 2 bytes, if any. masm.bind(compare2Bytes); - if (hasCBcond) { - masm.cbcondx(Less, result, 2, compare1Byte); - } else { - masm.cmp(result, 2); - masm.bpcc(Less, NOT_ANNUL, compare1Byte, Xcc, PREDICT_TAKEN); - masm.nop(); - } + masm.compareBranch(result, 2, Less, Xcc, compare1Byte, PREDICT_TAKEN, null); masm.lduh(new SPARCAddress(array1, 0), tempReg1); masm.lduh(new SPARCAddress(array2, 0), tempReg2); - if (hasCBcond) { - masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel); - } else { - masm.cmp(tempReg1, tempReg2); - masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN); - masm.nop(); - } + 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) { @@ -266,22 +222,11 @@ // Compare trailing byte, if any. masm.bind(compare1Byte); - if (hasCBcond) { - masm.cbcondx(NotEqual, result, 1, trueLabel); - } else { - masm.cmp(result, 1); - masm.bpcc(NotEqual, NOT_ANNUL, trueLabel, Xcc, PREDICT_TAKEN); - masm.nop(); - } + masm.compareBranch(result, 1, NotEqual, Xcc, trueLabel, PREDICT_TAKEN, null); + masm.ldub(new SPARCAddress(array1, 0), tempReg1); masm.ldub(new SPARCAddress(array2, 0), tempReg2); - if (hasCBcond) { - masm.cbcondx(NotEqual, tempReg1, tempReg2, falseLabel); - } else { - masm.cmp(tempReg1, tempReg2); - masm.bpcc(NotEqual, NOT_ANNUL, falseLabel, Xcc, PREDICT_TAKEN); - masm.nop(); - } + masm.compareBranch(tempReg1, tempReg2, NotEqual, Xcc, falseLabel, PREDICT_TAKEN, null); } else { masm.bind(compare1Byte); } diff -r 24843a13b2af -r 9961439fc100 graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Thu Aug 06 16:05:23 2015 +0200 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Fri Aug 07 13:28:24 2015 +0200 @@ -240,26 +240,26 @@ case Int: if (isConstant(actualY)) { int constantY = asConstant(actualY).asInt(); - masm.cbcondw(conditionFlag, asIntReg(actualX), constantY, actualTrueTarget); + CBCOND.emit(masm, conditionFlag, false, asIntReg(actualX), constantY, actualTrueTarget); } else { - masm.cbcondw(conditionFlag, asIntReg(actualX), asIntReg(actualY), actualTrueTarget); + CBCOND.emit(masm, conditionFlag, false, asIntReg(actualX), asIntReg(actualY), actualTrueTarget); } break; case Long: if (isConstant(actualY)) { int constantY = (int) asConstant(actualY).asLong(); - masm.cbcondx(conditionFlag, asLongReg(actualX), constantY, actualTrueTarget); + CBCOND.emit(masm, conditionFlag, true, asLongReg(actualX), constantY, actualTrueTarget); } else { - masm.cbcondx(conditionFlag, asLongReg(actualX), asLongReg(actualY), actualTrueTarget); + CBCOND.emit(masm, conditionFlag, true, asLongReg(actualX), asLongReg(actualY), actualTrueTarget); } break; case Object: if (isConstant(actualY)) { // Object constant valid can only be null assert asConstant(actualY).isNull(); - masm.cbcondx(conditionFlag, asObjectReg(actualX), 0, actualTrueTarget); + CBCOND.emit(masm, conditionFlag, true, asObjectReg(actualX), 0, actualTrueTarget); } else { // this is already loaded - masm.cbcondx(conditionFlag, asObjectReg(actualX), asObjectReg(actualY), actualTrueTarget); + CBCOND.emit(masm, conditionFlag, true, asObjectReg(actualX), asObjectReg(actualY), actualTrueTarget); } break; default: @@ -486,19 +486,11 @@ boolean canUseShortBranch = masm.hasFeature(CPUFeature.CBCOND) && isShortBranch(masm, cbCondPosition, hint, target); if (bits != null && canUseShortBranch) { if (isShortConstant) { - if (conditionCode == Icc) { - masm.cbcondw(conditionFlag, keyRegister, (int) (long) bits, target); - } else { - masm.cbcondx(conditionFlag, keyRegister, (int) (long) bits, target); - } + CBCOND.emit(masm, conditionFlag, conditionCode == Icc, keyRegister, (int) (long) bits, target); } else { Register scratchRegister = asRegister(scratch); const2reg(crb, masm, scratch, constantBaseRegister, keyConstants[index], SPARCDelayedControlTransfer.DUMMY); - if (conditionCode == Icc) { - masm.cbcondw(conditionFlag, keyRegister, scratchRegister, target); - } else { - masm.cbcondx(conditionFlag, keyRegister, scratchRegister, target); - } + CBCOND.emit(masm, conditionFlag, conditionCode == Icc, keyRegister, scratchRegister, target); } } else { if (bits != null && isSimm13(constant)) { diff -r 24843a13b2af -r 9961439fc100 graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java --- a/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Thu Aug 06 16:05:23 2015 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot.sparc/src/com/oracle/graal/truffle/hotspot/sparc/SPARCOptimizedCallTargetInstumentationFactory.java Fri Aug 07 13:28:24 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -22,13 +22,11 @@ */ package com.oracle.graal.truffle.hotspot.sparc; -import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import static jdk.internal.jvmci.code.CallingConvention.Type.*; import static jdk.internal.jvmci.meta.Kind.*; -import static jdk.internal.jvmci.sparc.SPARC.CPUFeature.*; import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.hotspot.*; import jdk.internal.jvmci.meta.*; @@ -36,7 +34,7 @@ import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.ScratchRegister; import com.oracle.graal.compiler.common.spi.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.asm.*; @@ -62,13 +60,7 @@ SPARCAddress verifiedEntryPointAddress = new SPARCAddress(spillRegister, config.nmethodEntryOffset); asm.ldx(codeBlobAddress, spillRegister); - if (asm.hasFeature(CBCOND)) { - asm.cbcondx(Equal, spillRegister, 0, doProlog); - } else { - asm.cmp(spillRegister, 0); - asm.bpcc(Equal, NOT_ANNUL, doProlog, Xcc, PREDICT_NOT_TAKEN); - asm.nop(); - } + asm.compareBranch(spillRegister, 0, Equal, Xcc, doProlog, PREDICT_NOT_TAKEN, null); asm.ldx(verifiedEntryPointAddress, spillRegister); // in delay slot asm.jmp(spillRegister); asm.nop();