// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/compiler/backend/instruction-scheduler.h"

namespace v8 {
namespace internal {
namespace compiler {

bool InstructionScheduler::SchedulerSupported() { return true; }

int InstructionScheduler::GetTargetInstructionFlags(
    const Instruction* instr) const {
  switch (instr->arch_opcode()) {
    case kArmAdd:
    case kArmAnd:
    case kArmBic:
    case kArmClz:
    case kArmCmp:
    case kArmCmn:
    case kArmTst:
    case kArmTeq:
    case kArmOrr:
    case kArmEor:
    case kArmSub:
    case kArmRsb:
    case kArmMul:
    case kArmMla:
    case kArmMls:
    case kArmSmmul:
    case kArmSmull:
    case kArmSmmla:
    case kArmUmull:
    case kArmSdiv:
    case kArmUdiv:
    case kArmMov:
    case kArmMvn:
    case kArmBfc:
    case kArmUbfx:
    case kArmSbfx:
    case kArmSxtb:
    case kArmSxth:
    case kArmSxtab:
    case kArmSxtah:
    case kArmUxtb:
    case kArmUxth:
    case kArmUxtab:
    case kArmUxtah:
    case kArmRbit:
    case kArmRev:
    case kArmAddPair:
    case kArmSubPair:
    case kArmMulPair:
    case kArmLslPair:
    case kArmLsrPair:
    case kArmAsrPair:
    case kArmVcmpF32:
    case kArmVaddF32:
    case kArmVsubF32:
    case kArmVmulF32:
    case kArmVmlaF32:
    case kArmVmlsF32:
    case kArmVdivF32:
    case kArmVabsF32:
    case kArmVnegF32:
    case kArmVsqrtF32:
    case kArmVcmpF64:
    case kArmVaddF64:
    case kArmVsubF64:
    case kArmVmulF64:
    case kArmVmlaF64:
    case kArmVmlsF64:
    case kArmVdivF64:
    case kArmVmodF64:
    case kArmVabsF64:
    case kArmVnegF64:
    case kArmVsqrtF64:
    case kArmVrintmF32:
    case kArmVrintmF64:
    case kArmVrintpF32:
    case kArmVrintpF64:
    case kArmVrintzF32:
    case kArmVrintzF64:
    case kArmVrintaF64:
    case kArmVrintnF32:
    case kArmVrintnF64:
    case kArmVcvtF32F64:
    case kArmVcvtF64F32:
    case kArmVcvtF32S32:
    case kArmVcvtF32U32:
    case kArmVcvtF64S32:
    case kArmVcvtF64U32:
    case kArmVcvtS32F32:
    case kArmVcvtU32F32:
    case kArmVcvtS32F64:
    case kArmVcvtU32F64:
    case kArmVmovU32F32:
    case kArmVmovF32U32:
    case kArmVmovLowU32F64:
    case kArmVmovLowF64U32:
    case kArmVmovHighU32F64:
    case kArmVmovHighF64U32:
    case kArmVmovF64U32U32:
    case kArmVmovU32U32F64:
    case kArmFloat32Max:
    case kArmFloat64Max:
    case kArmFloat32Min:
    case kArmFloat64Min:
    case kArmFloat64SilenceNaN:
    case kArmF32x4Splat:
    case kArmF32x4ExtractLane:
    case kArmF32x4ReplaceLane:
    case kArmF32x4SConvertI32x4:
    case kArmF32x4UConvertI32x4:
    case kArmF32x4Abs:
    case kArmF32x4Neg:
    case kArmF32x4Sqrt:
    case kArmF32x4RecipApprox:
    case kArmF32x4RecipSqrtApprox:
    case kArmF32x4Add:
    case kArmF32x4AddHoriz:
    case kArmF32x4Sub:
    case kArmF32x4Mul:
    case kArmF32x4Div:
    case kArmF32x4Min:
    case kArmF32x4Max:
    case kArmF32x4Eq:
    case kArmF32x4Ne:
    case kArmF32x4Lt:
    case kArmF32x4Le:
    case kArmI32x4Splat:
    case kArmI32x4ExtractLane:
    case kArmI32x4ReplaceLane:
    case kArmI32x4SConvertF32x4:
    case kArmI32x4SConvertI16x8Low:
    case kArmI32x4SConvertI16x8High:
    case kArmI32x4Neg:
    case kArmI32x4Shl:
    case kArmI32x4ShrS:
    case kArmI32x4Add:
    case kArmI32x4AddHoriz:
    case kArmI32x4Sub:
    case kArmI32x4Mul:
    case kArmI32x4MinS:
    case kArmI32x4MaxS:
    case kArmI32x4Eq:
    case kArmI32x4Ne:
    case kArmI32x4GtS:
    case kArmI32x4GeS:
    case kArmI32x4UConvertF32x4:
    case kArmI32x4UConvertI16x8Low:
    case kArmI32x4UConvertI16x8High:
    case kArmI32x4ShrU:
    case kArmI32x4MinU:
    case kArmI32x4MaxU:
    case kArmI32x4GtU:
    case kArmI32x4GeU:
    case kArmI16x8Splat:
    case kArmI16x8ExtractLane:
    case kArmI16x8ReplaceLane:
    case kArmI16x8SConvertI8x16Low:
    case kArmI16x8SConvertI8x16High:
    case kArmI16x8Neg:
    case kArmI16x8Shl:
    case kArmI16x8ShrS:
    case kArmI16x8SConvertI32x4:
    case kArmI16x8Add:
    case kArmI16x8AddSaturateS:
    case kArmI16x8AddHoriz:
    case kArmI16x8Sub:
    case kArmI16x8SubSaturateS:
    case kArmI16x8Mul:
    case kArmI16x8MinS:
    case kArmI16x8MaxS:
    case kArmI16x8Eq:
    case kArmI16x8Ne:
    case kArmI16x8GtS:
    case kArmI16x8GeS:
    case kArmI16x8UConvertI8x16Low:
    case kArmI16x8UConvertI8x16High:
    case kArmI16x8ShrU:
    case kArmI16x8UConvertI32x4:
    case kArmI16x8AddSaturateU:
    case kArmI16x8SubSaturateU:
    case kArmI16x8MinU:
    case kArmI16x8MaxU:
    case kArmI16x8GtU:
    case kArmI16x8GeU:
    case kArmI8x16Splat:
    case kArmI8x16ExtractLane:
    case kArmI8x16ReplaceLane:
    case kArmI8x16Neg:
    case kArmI8x16Shl:
    case kArmI8x16ShrS:
    case kArmI8x16SConvertI16x8:
    case kArmI8x16Add:
    case kArmI8x16AddSaturateS:
    case kArmI8x16Sub:
    case kArmI8x16SubSaturateS:
    case kArmI8x16Mul:
    case kArmI8x16MinS:
    case kArmI8x16MaxS:
    case kArmI8x16Eq:
    case kArmI8x16Ne:
    case kArmI8x16GtS:
    case kArmI8x16GeS:
    case kArmI8x16UConvertI16x8:
    case kArmI8x16AddSaturateU:
    case kArmI8x16SubSaturateU:
    case kArmI8x16ShrU:
    case kArmI8x16MinU:
    case kArmI8x16MaxU:
    case kArmI8x16GtU:
    case kArmI8x16GeU:
    case kArmS128Zero:
    case kArmS128Dup:
    case kArmS128And:
    case kArmS128Or:
    case kArmS128Xor:
    case kArmS128Not:
    case kArmS128Select:
    case kArmS32x4ZipLeft:
    case kArmS32x4ZipRight:
    case kArmS32x4UnzipLeft:
    case kArmS32x4UnzipRight:
    case kArmS32x4TransposeLeft:
    case kArmS32x4TransposeRight:
    case kArmS32x4Shuffle:
    case kArmS16x8ZipLeft:
    case kArmS16x8ZipRight:
    case kArmS16x8UnzipLeft:
    case kArmS16x8UnzipRight:
    case kArmS16x8TransposeLeft:
    case kArmS16x8TransposeRight:
    case kArmS8x16ZipLeft:
    case kArmS8x16ZipRight:
    case kArmS8x16UnzipLeft:
    case kArmS8x16UnzipRight:
    case kArmS8x16TransposeLeft:
    case kArmS8x16TransposeRight:
    case kArmS8x16Concat:
    case kArmS8x16Shuffle:
    case kArmS32x2Reverse:
    case kArmS16x4Reverse:
    case kArmS16x2Reverse:
    case kArmS8x8Reverse:
    case kArmS8x4Reverse:
    case kArmS8x2Reverse:
    case kArmS1x4AnyTrue:
    case kArmS1x4AllTrue:
    case kArmS1x8AnyTrue:
    case kArmS1x8AllTrue:
    case kArmS1x16AnyTrue:
    case kArmS1x16AllTrue:
      return kNoOpcodeFlags;

    case kArmVldrF32:
    case kArmVldrF64:
    case kArmVld1F64:
    case kArmVld1S128:
    case kArmLdrb:
    case kArmLdrsb:
    case kArmLdrh:
    case kArmLdrsh:
    case kArmLdr:
    case kArmPeek:
    case kArmWord32AtomicPairLoad:
      return kIsLoadOperation;

    case kArmVstrF32:
    case kArmVstrF64:
    case kArmVst1F64:
    case kArmVst1S128:
    case kArmStrb:
    case kArmStrh:
    case kArmStr:
    case kArmPush:
    case kArmPoke:
    case kArmDmbIsh:
    case kArmDsbIsb:
    case kArmWord32AtomicPairStore:
    case kArmWord32AtomicPairAdd:
    case kArmWord32AtomicPairSub:
    case kArmWord32AtomicPairAnd:
    case kArmWord32AtomicPairOr:
    case kArmWord32AtomicPairXor:
    case kArmWord32AtomicPairExchange:
    case kArmWord32AtomicPairCompareExchange:
      return kHasSideEffect;

#define CASE(Name) case k##Name:
      COMMON_ARCH_OPCODE_LIST(CASE)
#undef CASE
      // Already covered in architecture independent code.
      UNREACHABLE();
  }

  UNREACHABLE();
}

int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
  // TODO(all): Add instruction cost modeling.
  return 1;
}

}  // namespace compiler
}  // namespace internal
}  // namespace v8
