Exemple #1
0
void moveRR(Context* con, unsigned srcSize, lir::Register* src,
       unsigned dstSize, lir::Register* dst)
{
  bool srcIsFpr = isFpr(src);
  bool dstIsFpr = isFpr(dst);
  if (srcIsFpr || dstIsFpr) {   // FPR(s) involved
    assert(con, srcSize == dstSize);
    const bool dprec = srcSize == 8;
    if (srcIsFpr && dstIsFpr) { // FPR to FPR
      if (dprec) emit(con, fcpyd(fpr64(dst), fpr64(src))); // double
      else       emit(con, fcpys(fpr32(dst), fpr32(src))); // single
    } else if (srcIsFpr) {      // FPR to GPR
      if (dprec) emit(con, fmrrd(dst->low, dst->high, fpr64(src)));
      else       emit(con, fmrs(dst->low, fpr32(src)));
    } else {                    // GPR to FPR
      if (dprec) emit(con, fmdrr(fpr64(dst->low), src->low, src->high));
      else       emit(con, fmsr(fpr32(dst), src->low));
    }
    return;
  }

  switch (srcSize) {
  case 1:
    emit(con, lsli(dst->low, src->low, 24));
    emit(con, asri(dst->low, dst->low, 24));
    break;

  case 2:
    emit(con, lsli(dst->low, src->low, 16));
    emit(con, asri(dst->low, dst->low, 16));
    break;

  case 4:
  case 8:
    if (srcSize == 4 and dstSize == 8) {
      moveRR(con, 4, src, 4, dst);
      emit(con, asri(dst->high, src->low, 31));
    } else if (srcSize == 8 and dstSize == 8) {
      lir::Register srcHigh(src->high);
      lir::Register dstHigh(dst->high);

      if (src->high == dst->low) {
        if (src->low == dst->high) {
          swapRR(con, 4, src, 4, dst);
        } else {
          moveRR(con, 4, &srcHigh, 4, &dstHigh);
          moveRR(con, 4, src, 4, dst);
        }
      } else {
        moveRR(con, 4, src, 4, dst);
        moveRR(con, 4, &srcHigh, 4, &dstHigh);
      }
    } else if (src->low != dst->low) {
      emit(con, mov(dst->low, src->low));
    }
    break;

  default: abort(con);
  }
}
Exemple #2
0
std::string Move::format() const
{
    std::stringstream ret;
    ret << "MOVE [" << srcLow() << ", " << srcHigh() << ") to [" << destLow() <<  ", " << destHigh() << ")";
    return ret.str();
}