// Copyright (c) 2017 Google Inc.
//
// 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.

// Validates literal numbers.

#include "validate.h"

#include <cassert>

#include "diagnostic.h"
#include "opcode.h"
#include "val/instruction.h"
#include "val/validation_state.h"

namespace spvtools {
namespace {

// Returns true if the operand holds a literal number
bool IsLiteralNumber(const spv_parsed_operand_t* operand) {
  switch (operand->number_kind) {
    case SPV_NUMBER_SIGNED_INT:
    case SPV_NUMBER_UNSIGNED_INT:
    case SPV_NUMBER_FLOATING:
      return true;
    default:
      return false;
  }
}

// Verifies that the upper bits of the given upper |word| with given
// lower |width| are zero- or sign-extended when |signed_int| is true
bool VerifyUpperBits(uint32_t word, uint32_t width, bool signed_int) {
  assert(width < 32);
  assert(0 < width);
  const uint32_t upper_mask = 0xFFFFFFFFu << width;
  const uint32_t upper_bits = word & upper_mask;

  bool result = false;
  if (signed_int) {
    const uint32_t sign_bit = word & (1u << (width - 1));
    if (sign_bit) {
      result = upper_bits == upper_mask;
    } else {
      result = upper_bits == 0;
    }
  } else {
    result = upper_bits == 0;
  }
  return result;
}

}  // namespace

// Validates that literal numbers are represented according to the spec
spv_result_t LiteralsPass(ValidationState_t& _,
                          const spv_parsed_instruction_t* inst) {
  // For every operand that is a literal number
  for (uint16_t i = 0; i < inst->num_operands; i++) {
    const spv_parsed_operand_t* operand = inst->operands + i;
    if (!IsLiteralNumber(operand)) continue;

    // The upper bits are always in the last word (little-endian)
    int last_index = operand->offset + operand->num_words - 1;
    const uint32_t upper_word = inst->words[last_index];

    // TODO(jcaraban): is the |word size| defined in some header?
    const uint32_t word_size = 32;
    uint32_t bit_width = operand->number_bit_width;

    // Bit widths that are a multiple of the word size have no upper bits
    const auto remaining_value_bits = bit_width % word_size;
    if (remaining_value_bits == 0) continue;

    const bool signedness = operand->number_kind == SPV_NUMBER_SIGNED_INT;

    if (!VerifyUpperBits(upper_word, remaining_value_bits, signedness)) {
      return _.diag(SPV_ERROR_INVALID_VALUE)
             << "The high-order bits of a literal number in instruction <id> "
             << inst->result_id << " must be 0 for a floating-point type, "
             << "or 0 for an integer type with Signedness of 0, "
             << "or sign extended when Signedness is 1";
    }
  }
  return SPV_SUCCESS;
}

}  // namespace spvtools
