/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "common_arm64.h"
#include "nodes_shared.h"

namespace art {

using helpers::CanFitInShifterOperand;

void HDataProcWithShifterOp::GetOpInfoFromInstruction(HInstruction* instruction,
                                                      /*out*/OpKind* op_kind,
                                                      /*out*/int* shift_amount) {
  DCHECK(CanFitInShifterOperand(instruction));
  if (instruction->IsShl()) {
    *op_kind = kLSL;
    *shift_amount = instruction->AsShl()->GetRight()->AsIntConstant()->GetValue();
  } else if (instruction->IsShr()) {
    *op_kind = kASR;
    *shift_amount = instruction->AsShr()->GetRight()->AsIntConstant()->GetValue();
  } else if (instruction->IsUShr()) {
    *op_kind = kLSR;
    *shift_amount = instruction->AsUShr()->GetRight()->AsIntConstant()->GetValue();
  } else {
    DCHECK(instruction->IsTypeConversion());
    Primitive::Type result_type = instruction->AsTypeConversion()->GetResultType();
    Primitive::Type input_type = instruction->AsTypeConversion()->GetInputType();
    int result_size = Primitive::ComponentSize(result_type);
    int input_size = Primitive::ComponentSize(input_type);
    int min_size = std::min(result_size, input_size);
    if (result_type == Primitive::kPrimInt && input_type == Primitive::kPrimLong) {
      // There is actually nothing to do. On ARM the high register from the
      // pair will be ignored. On ARM64 the register will be used as a W
      // register, discarding the top bits. This is represented by the
      // default encoding 'LSL 0'.
      *op_kind = kLSL;
      *shift_amount = 0;
    } else if (result_type == Primitive::kPrimChar ||
               (input_type == Primitive::kPrimChar && input_size < result_size)) {
      *op_kind = kUXTH;
    } else {
      switch (min_size) {
        case 1: *op_kind = kSXTB; break;
        case 2: *op_kind = kSXTH; break;
        case 4: *op_kind = kSXTW; break;
        default:
          LOG(FATAL) << "Unexpected min size " << min_size;
      }
    }
  }
}

std::ostream& operator<<(std::ostream& os, const HDataProcWithShifterOp::OpKind op) {
  switch (op) {
    case HDataProcWithShifterOp::kLSL:  return os << "LSL";
    case HDataProcWithShifterOp::kLSR:  return os << "LSR";
    case HDataProcWithShifterOp::kASR:  return os << "ASR";
    case HDataProcWithShifterOp::kUXTB: return os << "UXTB";
    case HDataProcWithShifterOp::kUXTH: return os << "UXTH";
    case HDataProcWithShifterOp::kUXTW: return os << "UXTW";
    case HDataProcWithShifterOp::kSXTB: return os << "SXTB";
    case HDataProcWithShifterOp::kSXTH: return os << "SXTH";
    case HDataProcWithShifterOp::kSXTW: return os << "SXTW";
    default:
      LOG(FATAL) << "Invalid OpKind " << static_cast<int>(op);
      UNREACHABLE();
  }
}

}  // namespace art
