public static void emitRem( CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Value src2, Value scratch1, Value scratch2, LIRFrameState info, SPARCDelayedControlTransfer delaySlotLir) { int exceptionOffset = -1; if (!isConstant(src1) && isConstant(src2)) { assert isSimm13(crb.asIntConst(src2)); assert !src1.equals(scratch1); assert !src1.equals(scratch2); assert !src2.equals(scratch1); switch (opcode) { case IREM: new Sra(asIntReg(src1), 0, asIntReg(dst)).emit(masm); exceptionOffset = masm.position(); new Sdivx(asIntReg(dst), crb.asIntConst(src2), asIntReg(scratch1)).emit(masm); new Mulx(asIntReg(scratch1), crb.asIntConst(src2), asIntReg(scratch2)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); new Sub(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm); break; case LREM: exceptionOffset = masm.position(); new Sdivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm); break; case LUREM: exceptionOffset = masm.position(); new Udivx(asLongReg(src1), crb.asIntConst(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), crb.asIntConst(src2), asLongReg(scratch2)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(src1), asLongReg(scratch2), asLongReg(dst)).emit(masm); break; case IUREM: GraalInternalError.unimplemented(); break; default: throw GraalInternalError.shouldNotReachHere(); } } else if (isRegister(src1) && isRegister(src2)) { Value srcLeft = src1; switch (opcode) { case LREM: if (isConstant(src1)) { new Setx(crb.asLongConst(src1), asLongReg(scratch2), false).emit(masm); srcLeft = scratch2; } assert !asLongReg(srcLeft).equals(asLongReg(scratch1)); assert !asLongReg(src2).equals(asLongReg(scratch1)); // But src2 can be scratch2 exceptionOffset = masm.position(); new Sdivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm); break; case LUREM: if (isConstant(src1)) { new Setx(crb.asLongConst(src1), asLongReg(scratch2), false).emit(masm); srcLeft = scratch2; } assert !asLongReg(srcLeft).equals(asLongReg(scratch1)); assert !asLongReg(src2).equals(asLongReg(scratch1)); exceptionOffset = masm.position(); new Udivx(asLongReg(srcLeft), asLongReg(src2), asLongReg(scratch1)).emit(masm); new Mulx(asLongReg(scratch1), asLongReg(src2), asLongReg(scratch1)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); new Sub(asLongReg(srcLeft), asLongReg(scratch1), asLongReg(dst)).emit(masm); break; case IREM: if (isConstant(src1)) { new Setx(crb.asIntConst(src1), asIntReg(scratch2), false).emit(masm); srcLeft = scratch2; } assert !asIntReg(srcLeft).equals(asIntReg(scratch1)); assert !asIntReg(src2).equals(asIntReg(scratch1)); new Sra(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm); new Sra(asIntReg(src2), 0, asIntReg(scratch2)).emit(masm); exceptionOffset = masm.position(); new Sdivx(asIntReg(scratch1), asIntReg(scratch2), asIntReg(dst)).emit(masm); new Mulx(asIntReg(dst), asIntReg(scratch2), asIntReg(dst)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm); break; case IUREM: assert !asIntReg(dst).equals(asIntReg(scratch1)); assert !asIntReg(dst).equals(asIntReg(scratch2)); new Srl(asIntReg(src1), 0, asIntReg(scratch1)).emit(masm); new Srl(asIntReg(src2), 0, asIntReg(dst)).emit(masm); exceptionOffset = masm.position(); new Udivx(asIntReg(scratch1), asIntReg(dst), asIntReg(scratch2)).emit(masm); new Mulx(asIntReg(scratch2), asIntReg(dst), asIntReg(dst)).emit(masm); delaySlotLir.emitControlTransfer(crb, masm); new Sub(asIntReg(scratch1), asIntReg(dst), asIntReg(dst)).emit(masm); break; default: throw GraalInternalError.shouldNotReachHere(); } } else { throw GraalInternalError.shouldNotReachHere(); } if (info != null) { assert exceptionOffset != -1; crb.recordImplicitException(exceptionOffset, info); } }
private static void emitRegConstant( CompilationResultBuilder crb, SPARCMacroAssembler masm, SPARCArithmetic opcode, Value dst, Value src1, Constant src2, LIRFrameState info, SPARCDelayedControlTransfer delaySlotLir) { assert isSimm13(crb.asIntConst(src2)) : src2; int constant = crb.asIntConst(src2); int exceptionOffset = -1; delaySlotLir.emitControlTransfer(crb, masm); switch (opcode) { case IADD: new Add(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case ISUB: new Sub(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case IMUL: new Mulx(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case IDIV: new Sdivx(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case IUDIV: new Udivx(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case IAND: new And(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case ISHL: new Sll(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case ISHR: new Sra(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case IUSHR: new Srl(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case IOR: new Or(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case IXOR: new Xor(asIntReg(src1), constant, asIntReg(dst)).emit(masm); break; case LADD: new Add(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LSUB: new Sub(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LMUL: new Mulx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LDIV: exceptionOffset = masm.position(); new Sdivx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LUDIV: exceptionOffset = masm.position(); new Udivx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LAND: new And(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LOR: new Or(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LXOR: new Xor(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LSHL: new Sllx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LSHR: new Srax(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case LUSHR: new Srlx(asLongReg(src1), constant, asLongReg(dst)).emit(masm); break; case DAND: // Has no constant implementation in SPARC case FADD: case FMUL: case FDIV: case DADD: case DMUL: case DDIV: default: throw GraalInternalError.shouldNotReachHere(); } if (info != null) { assert exceptionOffset != -1; crb.recordImplicitException(exceptionOffset, info); } }