# HG changeset patch # User Doug Simon # Date 1421091566 -3600 # Node ID edbac8edc2e1743fcf1dffb2f188dc4e2582c656 # Parent f57d86eb036fe568b055560388ca9ebff77049bc# Parent 5e80dd2f1783297c3b6823bca111768336be40aa Merge. diff -r f57d86eb036f -r edbac8edc2e1 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 Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Mon Jan 12 20:39:26 2015 +0100 @@ -53,6 +53,13 @@ void emit(SPARCAssembler masm); } + public static final int CCR_ICC_SHIFT = 0; + public static final int CCR_XCC_SHIFT = 4; + public static final int CCR_C_SHIFT = 0; + public static final int CCR_V_SHIFT = 1; + public static final int CCR_Z_SHIFT = 2; + public static final int CCR_N_SHIFT = 3; + // @formatter:off /** * Instruction format for Fmt00 instructions. This abstraction is needed as it @@ -1468,19 +1475,6 @@ } } - public static class Fmt4d { - - public Fmt4d(SPARCAssembler masm, int op, int op3, int cond, int cc, int simm11, int rd) { - assert op == 2; - assert op3 >= 0 && op3 < 0x40; - assert cc >= 0 && cc < 0x8; - assert cond >= 0 && cond < 0x10; - assert rd >= 0 && rd < 0x20; - - masm.emitInt(op << 30 | rd << 25 | op3 << 19 | ImmedTrue | ((cc << 15) & 0x00040000) | cond << 14 | ((cc << 11) & 0x3) | simm11 & 0x00004000); - } - } - public static class Fmt5a { public Fmt5a(SPARCAssembler masm, int op, int op3, int op5, int rs1, int rs2, int rs3, int rd) { @@ -1588,10 +1582,11 @@ Orncc(0x16, "orncc"), Xnorcc(0x17, "xnorcc"), Addccc(0x18, "addccc"), - Mulxcc(0x19, "mulxcc"), + // dos not exist + // Mulxcc(0x19, "mulxcc"), Umulcc(0x1A, "umulcc"), Smulcc(0x1B, "smulcc"), - Subccc(0x1C0, "subccc"), + Subccc(0x1C, "subccc"), Udivcc(0x1E, "udivcc"), Sdivcc(0x1F, "sdivcc"), @@ -1655,8 +1650,10 @@ Stf (0b10_0100, "stf"), Stfsr (0b10_0101, "stfsr"), Staf (0x10_0110, "staf"), + Rd (0b10_1000, "rd"), Stdf (0b10_0111, "stdf"), + Wr (0b11_0000, "wr"), Fcmp (0b11_0101, "fcmp"), Ldxa (0b01_1011, "ldxa"), @@ -1814,6 +1811,7 @@ Movxtod(0x118, "movxtod"), Movwtos(0b1_0001_1001, "movwtos"), UMulxhi(0b0_0001_0110, "umulxhi"), + Lzcnt (0b0_0001_0111, "lzcnt"), // end VIS3 // start CAMMELLIA @@ -2395,6 +2393,14 @@ } } + public static class Lzcnt extends Fmt3p { + + public Lzcnt(Register src1, Register dst) { + /* VIS3 only */ + super(Ops.ArithOp, Op3s.Impdep1, Opfs.Lzcnt, g0, src1, dst); + } + } + public static class And extends Fmt10 { public And(Register src1, int simm13, Register dst) { @@ -3993,6 +3999,17 @@ } } + public static class SMulcc extends Fmt10 { + + public SMulcc(Register src1, int simm13, Register dst) { + super(Op3s.Smulcc, src1, simm13, dst); + } + + public SMulcc(Register src1, Register src2, Register dst) { + super(Op3s.Smulcc, src1, src2, dst); + } + } + public static class Or extends Fmt10 { public Or(Register src1, int simm13, Register dst) { diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Mon Jan 12 20:39:26 2015 +0100 @@ -266,7 +266,7 @@ @Override protected Value genIntegerAdd(Kind kind, Value x, Value y) { - return gen.emitAdd(x, y); + return gen.emitAdd(x, y, false); } @Override @@ -277,7 +277,7 @@ @Override protected Value genIntegerMul(Kind kind, Value x, Value y) { - return gen.emitMul(x, y); + return gen.emitMul(x, y, false); } @Override diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Mon Jan 12 20:39:26 2015 +0100 @@ -155,7 +155,7 @@ if (CodeUtil.isPowerOf2(scale)) { indexRegister = emitShl(longIndex, JavaConstant.forLong(CodeUtil.log2(scale))); } else { - indexRegister = emitMul(longIndex, JavaConstant.forLong(scale)); + indexRegister = emitMul(longIndex, JavaConstant.forLong(scale), false); } scaleEnum = Scale.Times1; @@ -179,7 +179,7 @@ indexRegister = displacementRegister; scaleEnum = Scale.Times1; } else { - baseRegister = emitAdd(baseRegister, displacementRegister); + baseRegister = emitAdd(baseRegister, displacementRegister, false); } } @@ -231,7 +231,7 @@ } @Override - public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) { + public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpLIRKind, double overflowProbability) { append(new BranchOp(ConditionFlag.Overflow, overflow, noOverflow, overflowProbability)); } @@ -498,7 +498,7 @@ } @Override - public Variable emitAdd(Value a, Value b) { + public Variable emitAdd(Value a, Value b, boolean setFlags) { switch (a.getKind().getStackKind()) { case Int: return emitBinary(IADD, true, a, b); @@ -514,7 +514,7 @@ } @Override - public Variable emitSub(Value a, Value b) { + public Variable emitSub(Value a, Value b, boolean setFlags) { switch (a.getKind().getStackKind()) { case Int: return emitBinary(ISUB, false, a, b); @@ -530,7 +530,7 @@ } @Override - public Variable emitMul(Value a, Value b) { + public Variable emitMul(Value a, Value b, boolean setFlags) { switch (a.getKind().getStackKind()) { case Int: return emitBinary(IMUL, true, a, b); diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Mon Jan 12 20:39:26 2015 +0100 @@ -142,7 +142,7 @@ if (baseRegister.equals(Value.ILLEGAL)) { baseRegister = asAllocatable(indexRegister); } else { - baseRegister = emitAdd(baseRegister, indexRegister); + baseRegister = emitAdd(baseRegister, indexRegister, false); } } } @@ -201,7 +201,7 @@ } @Override - public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) { + public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpLIRKind, double overflowProbability) { throw GraalInternalError.unimplemented(); } @@ -321,7 +321,7 @@ } @Override - public Variable emitAdd(Value a, Value b) { + public Variable emitAdd(Value a, Value b, boolean setFlags) { Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind()) { case Int: @@ -346,7 +346,7 @@ } @Override - public Variable emitSub(Value a, Value b) { + public Variable emitSub(Value a, Value b, boolean setFlags) { Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind()) { case Int: @@ -368,7 +368,7 @@ } @Override - public Variable emitMul(Value a, Value b) { + public Variable emitMul(Value a, Value b, boolean setFlags) { Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind()) { case Int: diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java --- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java Mon Jan 12 20:39:26 2015 +0100 @@ -171,7 +171,7 @@ if (CodeUtil.isPowerOf2(scale)) { indexRegister = emitShl(convertedIndex, JavaConstant.forInt(CodeUtil.log2(scale))); } else { - indexRegister = emitMul(convertedIndex, JavaConstant.forInt(scale)); + indexRegister = emitMul(convertedIndex, JavaConstant.forInt(scale), false); } } else { indexRegister = convertedIndex; @@ -181,7 +181,7 @@ } else { Variable longBaseRegister = newVariable(LIRKind.derivedReference(Kind.Long)); emitMove(longBaseRegister, baseRegister); - baseRegister = emitAdd(longBaseRegister, indexRegister); + baseRegister = emitAdd(longBaseRegister, indexRegister, false); } } } @@ -255,7 +255,7 @@ } @Override - public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) { + public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpLIRKind, double overflowProbability) { throw GraalInternalError.unimplemented("PTXLIRGenerator.emitOverflowCheckBranch()"); } @@ -391,7 +391,7 @@ } @Override - public Variable emitAdd(Value a, Value b) { + public Variable emitAdd(Value a, Value b, boolean setFlags) { Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind()) { case Int: @@ -413,7 +413,7 @@ } @Override - public Variable emitSub(Value a, Value b) { + public Variable emitSub(Value a, Value b, boolean setFlags) { Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind()) { case Int: @@ -435,7 +435,7 @@ } @Override - public Variable emitMul(Value a, Value b) { + public Variable emitMul(Value a, Value b, boolean setFlags) { Variable result = newVariable(LIRKind.derive(a, b)); switch (a.getKind()) { case Int: diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Mon Jan 12 20:39:26 2015 +0100 @@ -145,7 +145,7 @@ if (CodeUtil.isPowerOf2(scale)) { indexRegister = emitShl(longIndex, JavaConstant.forLong(CodeUtil.log2(scale))); } else { - indexRegister = emitMul(longIndex, JavaConstant.forLong(scale)); + indexRegister = emitMul(longIndex, JavaConstant.forLong(scale), false); } } else { indexRegister = asAllocatable(index); @@ -171,7 +171,7 @@ } else { Variable longBaseRegister = newVariable(LIRKind.derivedReference(Kind.Long)); emitMove(longBaseRegister, baseRegister); - baseRegister = emitAdd(longBaseRegister, JavaConstant.forLong(finalDisp)); + baseRegister = emitAdd(longBaseRegister, JavaConstant.forLong(finalDisp), false); } } } @@ -253,8 +253,9 @@ } @Override - public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability) { - append(new BranchOp(ConditionFlag.OverflowSet, overflow, noOverflow, Kind.Long)); + public void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpLIRKind, double overflowProbability) { + Kind cmpKind = (Kind) cmpLIRKind.getPlatformKind(); + append(new BranchOp(ConditionFlag.OverflowSet, overflow, noOverflow, cmpKind)); } @Override @@ -584,12 +585,12 @@ } @Override - public Variable emitAdd(Value a, Value b) { + public Variable emitAdd(Value a, Value b, boolean setFlags) { switch (a.getKind().getStackKind()) { case Int: - return emitBinary(IADD, true, a, b); + return emitBinary(setFlags ? IADDCC : IADD, true, a, b); case Long: - return emitBinary(LADD, true, a, b); + return emitBinary(setFlags ? LADDCC : LADD, true, a, b); case Float: return emitBinary(FADD, true, a, b); case Double: @@ -600,12 +601,12 @@ } @Override - public Variable emitSub(Value a, Value b) { + public Variable emitSub(Value a, Value b, boolean setFlags) { switch (a.getKind().getStackKind()) { case Int: - return emitBinary(ISUB, false, a, b); + return emitBinary(setFlags ? ISUBCC : ISUB, false, a, b); case Long: - return emitBinary(LSUB, false, a, b); + return emitBinary(setFlags ? LSUBCC : LSUB, false, a, b); case Float: return emitBinary(FSUB, false, a, b); case Double: @@ -616,12 +617,18 @@ } @Override - public Variable emitMul(Value a, Value b) { + public Variable emitMul(Value a, Value b, boolean setFlags) { switch (a.getKind().getStackKind()) { case Int: - return emitBinary(IMUL, true, a, b); + return emitBinary(setFlags ? IMULCC : IMUL, true, a, b); case Long: - return emitBinary(LMUL, true, a, b); + if (setFlags) { + Variable result = newVariable(LIRKind.derive(a, b)); + append(new SPARCLMulccOp(result, a, b, this)); + return result; + } else { + return emitBinary(LMUL, true, a, b); + } case Float: return emitBinary(FMUL, true, a, b); case Double: diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Mon Jan 12 20:39:26 2015 +0100 @@ -598,8 +598,10 @@ return getDebugInfoBuilder().build(state, exceptionEdge); } - public void emitOverflowCheckBranch(BeginNode overflowSuccessor, BeginNode next, double probability) { - gen.emitOverflowCheckBranch(getLIRBlock(overflowSuccessor), getLIRBlock(next), probability); + @Override + public void emitOverflowCheckBranch(BeginNode overflowSuccessor, BeginNode next, Stamp stamp, double probability) { + LIRKind cmpKind = getLIRGeneratorTool().getLIRKind(stamp); + gen.emitOverflowCheckBranch(getLIRBlock(overflowSuccessor), getLIRBlock(next), cmpKind, probability); } @Override diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Mon Jan 12 20:39:26 2015 +0100 @@ -85,10 +85,10 @@ assert !gen.getCodeCache().needsDataPatch(asConstant(offset)); Variable longAddress = gen.newVariable(LIRKind.value(Kind.Long)); gen.emitMove(longAddress, address); - address = getGen().emitAdd(longAddress, asConstant(offset)); + address = getGen().emitAdd(longAddress, asConstant(offset), false); } else { if (isLegal(offset)) { - address = getGen().emitAdd(address, offset); + address = getGen().emitAdd(address, offset, false); } } diff -r f57d86eb036f -r edbac8edc2e1 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 Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCArithmetic.java Mon Jan 12 20:39:26 2015 +0100 @@ -26,6 +26,7 @@ import static com.oracle.graal.asm.sparc.SPARCAssembler.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.sparc.*; @@ -34,11 +35,15 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.sparc.SPARC.CPUFeature; +import com.oracle.graal.sparc.*; public enum SPARCArithmetic { // @formatter:off IADD, ISUB, IMUL, IUMUL, IDIV, IREM, IUDIV, IUREM, IAND, IOR, IXOR, ISHL, ISHR, IUSHR, LADD, LSUB, LMUL, LUMUL, LDIV, LREM, LUDIV, LUREM, LAND, LOR, LXOR, LSHL, LSHR, LUSHR, + IADDCC, ISUBCC, IMULCC, + LADDCC, LSUBCC, LMULCC, FADD, FSUB, FMUL, FDIV, FREM, FAND, FOR, FXOR, DADD, DSUB, DMUL, DDIV, DREM, DAND, DOR, DXOR, INEG, LNEG, FNEG, DNEG, INOT, LNOT, @@ -175,6 +180,49 @@ } } + /** + * Calculates the product and condition code for long multiplication of long values. + */ + public static class SPARCLMulccOp extends SPARCLIRInstruction { + @Def({REG}) protected Value result; + @Alive({REG}) protected Value x; + @Alive({REG}) protected Value y; + @Temp({REG}) protected Value scratch1; + @Temp({REG}) protected Value scratch2; + + public SPARCLMulccOp(Value result, Value x, Value y, LIRGeneratorTool gen) { + this.result = result; + this.x = x; + this.y = y; + this.scratch1 = gen.newVariable(LIRKind.derive(x, y)); + this.scratch2 = gen.newVariable(LIRKind.derive(x, y)); + } + + @Override + public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { + Label noOverflow = new Label(); + new Mulx(asLongReg(x), asLongReg(y), asLongReg(result)).emit(masm); + + // Calculate the upper 64 bit signed := (umulxhi product - (x{63}&y + y{63}&x)) + new Umulxhi(asLongReg(x), asLongReg(y), asLongReg(scratch1)).emit(masm); + new Srax(asLongReg(x), 63, asLongReg(scratch2)).emit(masm); + new And(asLongReg(scratch2), asLongReg(y), asLongReg(scratch2)).emit(masm); + new Sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1)).emit(masm); + + new Srax(asLongReg(y), 63, asLongReg(scratch2)).emit(masm); + new And(asLongReg(scratch2), asLongReg(x), asLongReg(scratch2)).emit(masm); + new Sub(asLongReg(scratch1), asLongReg(scratch2), asLongReg(scratch1)).emit(masm); + + // Now construct the lower half and compare + new Srax(asLongReg(result), 63, asLongReg(scratch2)).emit(masm); + new Cmp(asLongReg(scratch1), asLongReg(scratch2)).emit(masm); + new Bpe(CC.Xcc, false, true, noOverflow).emit(masm); + new Nop().emit(masm); + new Wrccr(SPARC.g0, 1 << (CCR_XCC_SHIFT + CCR_V_SHIFT)).emit(masm); + masm.bind(noOverflow); + } + } + private static void emitRegConstant(CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, JavaConstant src2, LIRFrameState info, SPARCDelayedControlTransfer delaySlotLir) { assert isSimm13(crb.asIntConst(src2)) : src2; @@ -185,12 +233,20 @@ case IADD: new Add(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; + case IADDCC: + new Addcc(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + break; case ISUB: new Sub(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; + case ISUBCC: + new Subcc(asIntReg(src1), constant, asIntReg(dst)).emit(masm); + break; case IMUL: new Mulx(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; + case IMULCC: + throw GraalInternalError.unimplemented(); case IDIV: new Sdivx(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; @@ -218,9 +274,15 @@ case LADD: new Add(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; + case LADDCC: + new Addcc(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + break; case LSUB: new Sub(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; + case LSUBCC: + new Subcc(asLongReg(src1), constant, asLongReg(dst)).emit(masm); + break; case LMUL: new Mulx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; @@ -276,14 +338,42 @@ delaySlotLir.emitControlTransfer(crb, masm); new Add(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; + case IADDCC: + delaySlotLir.emitControlTransfer(crb, masm); + new Addcc(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + break; case ISUB: delaySlotLir.emitControlTransfer(crb, masm); new Sub(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; + case ISUBCC: + delaySlotLir.emitControlTransfer(crb, masm); + new Subcc(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + break; case IMUL: delaySlotLir.emitControlTransfer(crb, masm); new Mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); break; + case IMULCC: + try (SPARCScratchRegister tmpScratch = SPARCScratchRegister.get()) { + Register tmp = tmpScratch.getRegister(); + new Mulx(asIntReg(src1), asIntReg(src2), asIntReg(dst)).emit(masm); + Label noOverflow = new Label(); + new Sra(asIntReg(dst), 0, tmp).emit(masm); + new Xorcc(SPARC.g0, SPARC.g0, SPARC.g0).emit(masm); + if (masm.hasFeature(CPUFeature.CBCOND)) { + new CBcondx(ConditionFlag.Equal, tmp, asIntReg(dst), noOverflow).emit(masm); + // Is necessary, otherwise we will have a penalty of 5 cycles in S3 + new Nop().emit(masm); + } else { + new Cmp(tmp, asIntReg(dst)).emit(masm); + new Bpe(CC.Xcc, noOverflow).emit(masm); + new Nop().emit(masm); + } + new Wrccr(SPARC.g0, 1 << (SPARCAssembler.CCR_ICC_SHIFT + SPARCAssembler.CCR_V_SHIFT)).emit(masm); + masm.bind(noOverflow); + } + break; case IDIV: new Signx(asIntReg(src1), asIntReg(src1)).emit(masm); new Signx(asIntReg(src2), asIntReg(src2)).emit(masm); @@ -328,14 +418,24 @@ delaySlotLir.emitControlTransfer(crb, masm); new Add(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; + case LADDCC: + delaySlotLir.emitControlTransfer(crb, masm); + new Addcc(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + break; case LSUB: delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; + case LSUBCC: + delaySlotLir.emitControlTransfer(crb, masm); + new Subcc(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); + break; case LMUL: delaySlotLir.emitControlTransfer(crb, masm); new Mulx(asLongReg(src1), asLongReg(src2), asLongReg(dst)).emit(masm); break; + case LMULCC: + throw GraalInternalError.unimplemented(); case LDIV: delaySlotLir.emitControlTransfer(crb, masm); exceptionOffset = masm.position(); @@ -659,8 +759,11 @@ switch (opcode) { case IADD: + case IADDCC: case ISUB: + case ISUBCC: case IMUL: + case IMULCC: case IDIV: case IREM: case IAND: @@ -681,8 +784,11 @@ assert valid : "rk: " + rk + " xsk: " + xsk + " ysk: " + ysk; break; case LADD: + case LADDCC: case LSUB: + case LSUBCC: case LMUL: + case LMULCC: case LDIV: case LREM: case LAND: diff -r f57d86eb036f -r edbac8edc2e1 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 Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Mon Jan 12 20:39:26 2015 +0100 @@ -413,7 +413,7 @@ if (actualCondition != null) { emitBranch(masm, actualTarget, actualCondition, cc, false); } else if (actualConditionFlag != null) { - emitBranch(masm, actualTarget, actualConditionFlag); + emitBranch(masm, actualTarget, actualConditionFlag, cc); } else { GraalInternalError.shouldNotReachHere(); } @@ -475,8 +475,8 @@ } } - private static void emitBranch(SPARCMacroAssembler masm, Label target, ConditionFlag actualCondition) { - new Fmt00b(false, actualCondition, Op2s.Br, target).emit(masm); + private static void emitBranch(SPARCMacroAssembler masm, Label target, ConditionFlag actualCondition, CC cc) { + new Fmt00c(0, actualCondition, Op2s.Bp, cc, 0, target).emit(masm); } private static void emitBranch(SPARCMacroAssembler masm, Label target, Condition actualCondition, CC cc, boolean predictTaken) { diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGenerator.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGenerator.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/ArithmeticLIRGenerator.java Mon Jan 12 20:39:26 2015 +0100 @@ -29,6 +29,12 @@ /** * This interface can be used to generate LIR for arithmetic operations. + * + * The setFlags flag in emitAdd, emitSub and emitMul indicates, that the instruction must set the + * flags register to be used for a later branch. (On AMD64, the condition codes are set in every + * arithmetic instruction, but other architectures optionally set the flags register) If setFlags is + * set, the instruction must set the flags register; if false, the instruction may or may not set + * the flags register. */ public interface ArithmeticLIRGenerator { @@ -36,11 +42,11 @@ Value emitNegate(Value input); - Value emitAdd(Value a, Value b); + Value emitAdd(Value a, Value b, boolean setFlags); - Value emitSub(Value a, Value b); + Value emitSub(Value a, Value b, boolean setFlags); - Value emitMul(Value a, Value b); + Value emitMul(Value a, Value b, boolean setFlags); Value emitMulHigh(Value a, Value b); diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Mon Jan 12 20:39:26 2015 +0100 @@ -241,7 +241,7 @@ public abstract void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability); - public abstract void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability); + public abstract void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpKind, double overflowProbability); public abstract void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability); diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Mon Jan 12 20:39:26 2015 +0100 @@ -165,7 +165,7 @@ void emitCompareBranch(PlatformKind cmpKind, Value left, Value right, Condition cond, boolean unorderedIsTrue, LabelRef trueDestination, LabelRef falseDestination, double trueDestinationProbability); - void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, double overflowProbability); + void emitOverflowCheckBranch(LabelRef overflow, LabelRef noOverflow, LIRKind cmpKind, double overflowProbability); void emitIntegerTestBranch(Value left, Value right, LabelRef trueDestination, LabelRef falseDestination, double trueSuccessorProbability); diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java Mon Jan 12 20:39:26 2015 +0100 @@ -98,6 +98,6 @@ op1 = op2; op2 = tmp; } - builder.setResult(this, gen.emitAdd(op1, op2)); + builder.setResult(this, gen.emitAdd(op1, op2, false)); } } diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java Mon Jan 12 20:39:26 2015 +0100 @@ -106,6 +106,6 @@ op1 = op2; op2 = tmp; } - builder.setResult(this, gen.emitMul(op1, op2)); + builder.setResult(this, gen.emitMul(op1, op2, false)); } } diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java Mon Jan 12 20:39:26 2015 +0100 @@ -133,6 +133,6 @@ @Override public void generate(NodeMappableLIRBuilder builder, ArithmeticLIRGenerator gen) { - builder.setResult(this, gen.emitSub(builder.operand(getX()), builder.operand(getY()))); + builder.setResult(this, gen.emitSub(builder.operand(getX()), builder.operand(getY()), false)); } } diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeLIRBuilderTool.java Mon Jan 12 20:39:26 2015 +0100 @@ -27,6 +27,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.cfg.*; +import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -66,7 +67,7 @@ LIRGeneratorTool getLIRGeneratorTool(); - void emitOverflowCheckBranch(BeginNode overflowSuccessor, BeginNode next, double probability); + void emitOverflowCheckBranch(BeginNode overflowSuccessor, BeginNode next, Stamp compareStamp, double probability); Value[] visitInvokeArguments(CallingConvention cc, Collection arguments); diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ExactMathTest.java Mon Jan 12 20:39:26 2015 +0100 @@ -47,12 +47,20 @@ public void testAdd() { test("add", 1, 2); test("add", Integer.MAX_VALUE, 2); + test("add", Integer.MIN_VALUE, -1); + test("add", -1, 2); } @Test public void testMul() { test("mul", 1, 2); + test("mul", -1, 2); + test("mul", Integer.MIN_VALUE, 1); + test("mul", Integer.MIN_VALUE, 2); + test("mul", Integer.MIN_VALUE, Integer.MIN_VALUE); + test("mul", Integer.MAX_VALUE, 1); test("mul", Integer.MAX_VALUE, 2); + test("mul", Integer.MAX_VALUE, Integer.MAX_VALUE); } @Test @@ -90,6 +98,10 @@ test("longMul", (long) Integer.MAX_VALUE, 2L); test("longMul", (long) Integer.MIN_VALUE, 2L); test("longMul", Long.MAX_VALUE, 2L); + test("longMul", Long.MAX_VALUE, 1L); + test("longMul", Long.MAX_VALUE, Long.MAX_VALUE); + test("longMul", Long.MIN_VALUE, Long.MIN_VALUE); + test("longMul", Long.MIN_VALUE, Long.MAX_VALUE); } @Test diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java Mon Jan 12 20:39:26 2015 +0100 @@ -37,6 +37,6 @@ @Override protected Value generateArithmetic(NodeLIRBuilderTool gen) { - return gen.getLIRGeneratorTool().emitAdd(gen.operand(getX()), gen.operand(getY())); + return gen.getLIRGeneratorTool().emitAdd(gen.operand(getX()), gen.operand(getY()), true); } } diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Mon Jan 12 20:39:26 2015 +0100 @@ -69,7 +69,7 @@ @Override public void generate(NodeLIRBuilderTool generator) { generator.setResult(this, generateArithmetic(generator)); - generator.emitOverflowCheckBranch(getOverflowSuccessor(), getNext(), probability(getOverflowSuccessor())); + generator.emitOverflowCheckBranch(getOverflowSuccessor(), getNext(), stamp, probability(getOverflowSuccessor())); } protected abstract Value generateArithmetic(NodeLIRBuilderTool generator); diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java Mon Jan 12 20:39:26 2015 +0100 @@ -37,6 +37,6 @@ @Override protected Value generateArithmetic(NodeLIRBuilderTool gen) { - return gen.getLIRGeneratorTool().emitMul(gen.operand(getX()), gen.operand(getY())); + return gen.getLIRGeneratorTool().emitMul(gen.operand(getX()), gen.operand(getY()), true); } } diff -r f57d86eb036f -r edbac8edc2e1 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java Mon Jan 12 20:39:04 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java Mon Jan 12 20:39:26 2015 +0100 @@ -37,6 +37,6 @@ @Override protected Value generateArithmetic(NodeLIRBuilderTool gen) { - return gen.getLIRGeneratorTool().emitSub(gen.operand(getX()), gen.operand(getY())); + return gen.getLIRGeneratorTool().emitSub(gen.operand(getX()), gen.operand(getY()), true); } }