Beispiel #1
0
 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);
   }
 }