Example #1
0
void
IRTranslator::translateBranchOp(const NormalizedInstruction& i) {
  auto const op = i.op();
  assert(op == OpJmpZ || op == OpJmpNZ);

  Offset takenOffset    = i.offset() + i.imm[0].u_BA;
  Offset fallthruOffset = i.offset() + instrLen((Op*)(i.pc()));

  auto jmpFlags = instrJmpFlags(i);

  if (i.nextOffset == takenOffset) {
    always_assert(RuntimeOption::EvalJitPGORegionSelector == "hottrace");
    // invert the branch
    if (op == OpJmpZ) {
      HHIR_EMIT(JmpNZ, fallthruOffset, jmpFlags);
    } else {
      HHIR_EMIT(JmpZ,  fallthruOffset, jmpFlags);
    }
    return;
  }

  if (op == OpJmpZ) {
    HHIR_EMIT(JmpZ,  takenOffset, jmpFlags);
  } else {
    HHIR_EMIT(JmpNZ, takenOffset, jmpFlags);
  }
}
Example #2
0
void
IRTranslator::translateMIterInit(const NormalizedInstruction& i) {
  HHIR_EMIT(MIterInit,
            i.imm[0].u_IVA,
            i.offset() + i.imm[1].u_BA,
            i.imm[2].u_IVA,
            instrJmpFlags(i));
}
Example #3
0
void
IRTranslator::translateWIterNext(const NormalizedInstruction& i) {
  bool invertCond = false;
  Offset targetOffset = getBranchTarget(i, invertCond);

  HHIR_EMIT(WIterNext,
            i.imm[0].u_IVA,
            targetOffset,
            i.imm[2].u_IVA,
            invertCond,
            instrJmpFlags(i));
}
Example #4
0
void implCondJmp(HTS& env, Offset taken, bool negate, SSATmp* src) {
  auto const flags = instrJmpFlags(*env.currentNormalizedInstruction);
  if (flags & JmpFlagEndsRegion) {
    spillStack(env);
  }
  if ((flags & JmpFlagNextIsMerge) != 0) {
    prepareForHHBCMergePoint(env);
  }
  auto const target = getBlock(env, taken);
  assertx(target != nullptr);
  auto const boolSrc = gen(env, ConvCellToBool, src);
  gen(env, DecRef, src);
  gen(env, negate ? JmpZero : JmpNZero, target, boolSrc);
}
Example #5
0
void implCondJmp(HTS& env, Offset taken, bool negate, SSATmp* src) {
  auto const flags = instrJmpFlags(*env.currentNormalizedInstruction);
  if (flags & JmpFlagEndsRegion) {
    spillStack(env);
  }
  if (env.mode == IRGenMode::CFG && (flags & JmpFlagNextIsMerge)) {
    spillStack(env);
    bccfMergeSPHack(env);
  }
  auto const target = getBlock(env, taken);
  assert(target != nullptr);
  auto const boolSrc = gen(env, ConvCellToBool, src);
  gen(env, DecRef, src);
  gen(env, negate ? JmpZero : JmpNZero, target, boolSrc);
}
Example #6
0
void implCondJmp(HTS& env, Offset taken, bool negate, SSATmp* src) {
  auto const flags = instrJmpFlags(*env.currentNormalizedInstruction);
  if (flags & JmpFlagEndsRegion) {
    spillStack(env);
  }
  if (env.mode == IRGenMode::CFG && (flags & JmpFlagNextIsMerge)) {
    // Before jumping to a merge point we have to ensure that the
    // stack pointer is sync'ed.  Without an ExceptionBarrier the
    // SpillStack can be removed by DCE (especially since merge points
    // start with a DefSP to block SP-chain walking).
    gen(env, ExceptionBarrier, spillStack(env));
  }
  auto const target = getBlock(env, taken);
  assert(target != nullptr);
  auto const boolSrc = gen(env, ConvCellToBool, src);
  gen(env, DecRef, src);
  gen(env, negate ? JmpZero : JmpNZero, target, boolSrc);
}
Example #7
0
void emitDecodeCufIter(IRGS& env, int32_t iterId, Offset relOffset) {
  auto const src        = popC(env);
  auto const type       = src->type();
  if (type.subtypeOfAny(Type::Arr, Type::Str, Type::Obj)) {
    auto const res = gen(
      env,
      DecodeCufIter,
      Type::Bool,
      IterId(iterId),
      src,
      fp(env)
    );
    gen(env, DecRef, src);
    implCondJmp(env, bcOff(env) + relOffset, true, res);
  } else {
    gen(env, DecRef, src);
    jmpImpl(env,
            bcOff(env) + relOffset,
            instrJmpFlags(*env.currentNormalizedInstruction));
  }
}
Example #8
0
void emitJmpNS(HTS& env, Offset relOffset) {
  jmpImpl(env, bcOff(env) + relOffset,
    instrJmpFlags(*env.currentNormalizedInstruction));
}
Example #9
0
void emitJmp(HTS& env, Offset relOffset) {
  surpriseCheck(env, relOffset);
  auto const offset = bcOff(env) + relOffset;
  jmpImpl(env, offset, instrJmpFlags(*env.currentNormalizedInstruction));
}
Example #10
0
void
IRTranslator::translateDecodeCufIter(const NormalizedInstruction& i) {

  HHIR_EMIT(DecodeCufIter, i.imm[0].u_IVA, i.offset() + i.imm[1].u_BA,
            instrJmpFlags(i));
}
Example #11
0
void IRTranslator::translateJmpNS(const NormalizedInstruction& i) {
  HHIR_EMIT(JmpNS, i.offset() + i.imm[0].u_BA, instrJmpFlags(i));
}