<commit_before>//
//  Decoder.cpp
//  Clock Signal
//
//  Created by <NAME> on 30/12/20.
//  Copyright © 2020 <NAME>. All rights reserved.
//

#include "Decoder.hpp"

using namespace InstructionSet::PowerPC;

namespace {

template <Model model, bool validate_reserved_bits, Operation operation> Instruction instruction(uint32_t opcode, bool is_supervisor = false) {
	// If validation isn't required, there's nothing to do here.
	if constexpr (!validate_reserved_bits) {
		return Instruction(operation, opcode, is_supervisor);
	}

	// Otherwise, validation depends on operation
	// (and, in principle, processor model).
	switch(operation) {
		case Operation::addmex:		case Operation::addzex:
		case Operation::bcctrx:		case Operation::bclrx:
		case Operation::cntlzdx:	case Operation::cntlzwx:
		case Operation::extsbx:		case Operation::extshx:		case Operation::extswx:
		case Operation::fmulx:		case Operation::fmulsx:
		case Operation::negx:
		case Operation::subfmex:	case Operation::subfzex:
			if(opcode & 0b000000'00000'00000'11111'0000000000'0) return Instruction(opcode);
		break;

		case Operation::cmp:		case Operation::cmpl:
			if(opcode & 0b000000'00010'00000'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::cmpi:		case Operation::cmpli:
			if(opcode & 0b000000'00010'00000'00000'0000000000'0) return Instruction(opcode);
		break;

		case Operation::dcbf:		case Operation::dcbi:		case Operation::dcbst:
		case Operation::dcbt:		case Operation::dcbtst:		case Operation::dcbz:
			if(opcode & 0b000000'11111'00000'00000'0000000000'0) return Instruction(opcode);
		break;

		case Operation::crand:		case Operation::crandc:		case Operation::creqv:
		case Operation::crnand:		case Operation::crnor:		case Operation::cror:
		case Operation::crorc:		case Operation::crxor:
		case Operation::eciwx:		case Operation::ecowx:
		case Operation::lbzux:		case Operation::lbzx:
		case Operation::ldarx:
		case Operation::ldux:		case Operation::ldx:
		case Operation::lfdux:		case Operation::lfdx:
		case Operation::lfsux:		case Operation::lfsx:
		case Operation::lhaux:		case Operation::lhax:		case Operation::lhbrx:
		case Operation::lhzux:		case Operation::lhzx:
		case Operation::lswi:		case Operation::lswx:
		case Operation::lwarx:		case Operation::lwaux:		case Operation::lwax:		case Operation::lwbrx:
		case Operation::lwzux:		case Operation::lwzx:
		case Operation::mfspr:		case Operation::mftb:
		case Operation::mtspr:
		case Operation::stbux:		case Operation::stbx:
		case Operation::stdux:		case Operation::stdx:
		case Operation::stfdux:		case Operation::stfdx:
		case Operation::stfiwx:
		case Operation::stfsux:		case Operation::stfsx:
		case Operation::sthbrx:
		case Operation::sthux:		case Operation::sthx:
		case Operation::stswi:		case Operation::stswx:
		case Operation::stwbrx:
		case Operation::stwux:		case Operation::stwx:
		case Operation::td:			case Operation::tw:
			if(opcode & 0b000000'00000'00000'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::fabsx:		case Operation::fcfidx:
		case Operation::fctidx:		case Operation::fctidzx:
		case Operation::fctiwx:		case Operation::fctiwzx:
		case Operation::fmrx:		case Operation::fnabsx:
		case Operation::fnegx:		case Operation::frspx:
			if(opcode & 0b000000'00000'11111'00000'0000000000'0) return Instruction(opcode);
		break;

		case Operation::faddx:		case Operation::faddsx:
		case Operation::fdivx:		case Operation::fdivsx:
		case Operation::fsubx:		case Operation::fsubsx:
			if(opcode & 0b000000'00000'00000'00000'1111100000'0) return Instruction(opcode);
		break;

		case Operation::fcmpo:		case Operation::fcmpu:
			if(opcode & 0b000000'00011'00000'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::fresx:		case Operation::frsqrtex:
		case Operation::fsqrtx:		case Operation::fsqrtsx:
			if(opcode & 0b000000'00000'11111'00000'1111100000'1) return Instruction(opcode);
		break;

		case Operation::icbi:
			if(opcode & 0b000000'11111'00000'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::eieio:
		case Operation::isync:
		case Operation::rfi:
		case Operation::slbia:
		case Operation::sync:
		case Operation::tlbia:
		case Operation::tlbsync:
			if(opcode & 0b000000'11111'11111'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mcrf:		case Operation::mcrfs:
			if(opcode & 0b000000'00011'00011'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mcrxr:
			if(opcode & 0b000000'00011'11111'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mfcr:
		case Operation::mfmsr:
		case Operation::mtmsr:
			if(opcode & 0b000000'00000'11111'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mffsx:
		case Operation::mtfsb0x:
		case Operation::mtfsb1x:
			if(opcode & 0b000000'00000'11111'11111'0000000000'0) return Instruction(opcode);
		break;

		case Operation::mtfsfx:
			if(opcode & 0b000000'10000'00001'00000'0000000000'0) return Instruction(opcode);
		break;

		case Operation::mtfsfix:
			if(opcode & 0b000000'00011'11111'00001'0000000000'0) return Instruction(opcode);
		break;

		case Operation::mtsr:
			if(opcode & 0b000000'00000'10000'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mtsrin:
			if(opcode & 0b000000'00000'11111'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mulhdx:		case Operation::mulhdux:
		case Operation::mulhwx:		case Operation::mulhwux:
			if(opcode & 0b000000'00000'00000'00000'1000000000'0) return Instruction(opcode);
		break;

		case Operation::sc:
			if(opcode & 0b000000'11111'11111'11111'1111111110'1) return Instruction(opcode);
		break;

		case Operation::slbie:
		case Operation::tlbie:
			if(opcode & 0b000000'11111'11111'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::stwcx_:
			if(!(opcode & 0b000000'00000'00000'00000'0000000000'1)) return Instruction(opcode);
		break;

		case Operation::clcs:
			if(opcode & 0b000000'00000'00000'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::addx:		case Operation::addcx:		case Operation::addex:
		case Operation::addi:		case Operation::addic:		case Operation::addic_:
		case Operation::addis:<commit_msg>Add missing validations.<commit_after>//
//  Decoder.cpp
//  Clock Signal
//
//  Created by <NAME> on 30/12/20.
//  Copyright © 2020 <NAME>. All rights reserved.
//

#include "Decoder.hpp"

using namespace InstructionSet::PowerPC;

namespace {

template <Model model, bool validate_reserved_bits, Operation operation> Instruction instruction(uint32_t opcode, bool is_supervisor = false) {
	// If validation isn't required, there's nothing to do here.
	if constexpr (!validate_reserved_bits) {
		return Instruction(operation, opcode, is_supervisor);
	}

	// Otherwise, validation depends on operation
	// (and, in principle, processor model).
	switch(operation) {
		case Operation::absx:		case Operation::clcs:
		case Operation::nabsx:
		case Operation::addmex:		case Operation::addzex:
		case Operation::bcctrx:		case Operation::bclrx:
		case Operation::cntlzdx:	case Operation::cntlzwx:
		case Operation::extsbx:		case Operation::extshx:		case Operation::extswx:
		case Operation::fmulx:		case Operation::fmulsx:
		case Operation::negx:
		case Operation::subfmex:	case Operation::subfzex:
			if(opcode & 0b000000'00000'00000'11111'0000000000'0) return Instruction(opcode);
		break;

		case Operation::cmp:		case Operation::cmpl:
			if(opcode & 0b000000'00010'00000'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::cmpi:		case Operation::cmpli:
			if(opcode & 0b000000'00010'00000'00000'0000000000'0) return Instruction(opcode);
		break;

		case Operation::dcbf:		case Operation::dcbi:		case Operation::dcbst:
		case Operation::dcbt:		case Operation::dcbtst:		case Operation::dcbz:
			if(opcode & 0b000000'11111'00000'00000'0000000000'0) return Instruction(opcode);
		break;

		case Operation::crand:		case Operation::crandc:		case Operation::creqv:
		case Operation::crnand:		case Operation::crnor:		case Operation::cror:
		case Operation::crorc:		case Operation::crxor:
		case Operation::eciwx:		case Operation::ecowx:
		case Operation::lbzux:		case Operation::lbzx:
		case Operation::ldarx:
		case Operation::ldux:		case Operation::ldx:
		case Operation::lfdux:		case Operation::lfdx:
		case Operation::lfsux:		case Operation::lfsx:
		case Operation::lhaux:		case Operation::lhax:		case Operation::lhbrx:
		case Operation::lhzux:		case Operation::lhzx:
		case Operation::lswi:		case Operation::lswx:
		case Operation::lwarx:		case Operation::lwaux:		case Operation::lwax:		case Operation::lwbrx:
		case Operation::lwzux:		case Operation::lwzx:
		case Operation::mfspr:		case Operation::mftb:
		case Operation::mtspr:
		case Operation::stbux:		case Operation::stbx:
		case Operation::stdux:		case Operation::stdx:
		case Operation::stfdux:		case Operation::stfdx:
		case Operation::stfiwx:
		case Operation::stfsux:		case Operation::stfsx:
		case Operation::sthbrx:
		case Operation::sthux:		case Operation::sthx:
		case Operation::stswi:		case Operation::stswx:
		case Operation::stwbrx:
		case Operation::stwux:		case Operation::stwx:
		case Operation::td:			case Operation::tw:
			if(opcode & 0b000000'00000'00000'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::fabsx:		case Operation::fcfidx:
		case Operation::fctidx:		case Operation::fctidzx:
		case Operation::fctiwx:		case Operation::fctiwzx:
		case Operation::fmrx:		case Operation::fnabsx:
		case Operation::fnegx:		case Operation::frspx:
			if(opcode & 0b000000'00000'11111'00000'0000000000'0) return Instruction(opcode);
		break;

		case Operation::faddx:		case Operation::faddsx:
		case Operation::fdivx:		case Operation::fdivsx:
		case Operation::fsubx:		case Operation::fsubsx:
			if(opcode & 0b000000'00000'00000'00000'1111100000'0) return Instruction(opcode);
		break;

		case Operation::fcmpo:		case Operation::fcmpu:
			if(opcode & 0b000000'00011'00000'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::fresx:		case Operation::frsqrtex:
		case Operation::fsqrtx:		case Operation::fsqrtsx:
			if(opcode & 0b000000'00000'11111'00000'1111100000'1) return Instruction(opcode);
		break;

		case Operation::icbi:
			if(opcode & 0b000000'11111'00000'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::eieio:
		case Operation::isync:
		case Operation::rfi:
		case Operation::slbia:
		case Operation::sync:
		case Operation::tlbia:
		case Operation::tlbsync:
			if(opcode & 0b000000'11111'11111'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mcrf:		case Operation::mcrfs:
			if(opcode & 0b000000'00011'00011'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mcrxr:
			if(opcode & 0b000000'00011'11111'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mfcr:
		case Operation::mfmsr:
		case Operation::mtmsr:
			if(opcode & 0b000000'00000'11111'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mffsx:
		case Operation::mtfsb0x:
		case Operation::mtfsb1x:
			if(opcode & 0b000000'00000'11111'11111'0000000000'0) return Instruction(opcode);
		break;

		case Operation::mtfsfx:
			if(opcode & 0b000000'10000'00001'00000'0000000000'0) return Instruction(opcode);
		break;

		case Operation::mtfsfix:
			if(opcode & 0b000000'00011'11111'00001'0000000000'0) return Instruction(opcode);
		break;

		case Operation::mtsr:
			if(opcode & 0b000000'00000'10000'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mtsrin:		case Operation::mfsrin:
			if(opcode & 0b000000'00000'11111'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mfsr:
			if(opcode & 0b000000'00000'10000'11111'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mtcrf:
			if(opcode & 0b000000'00000'10000'00001'0000000000'1) return Instruction(opcode);
		break;

		case Operation::mulhdx:		case Operation::mulhdux:
		case Operation::mulhwx:		case Operation::mulhwux:
			if(opcode & 0b000000'00000'00000'00000'1000000000'0) return Instruction(opcode);
		break;

		case Operation::sc:
			if(opcode & 0b000000'11111'11111'11111'1111111110'1) return Instruction(opcode);
		break;

		case Operation::slbie:
		case Operation::tlbie:
			if(opcode & 0b000000'11111'11111'00000'0000000000'1) return Instruction(opcode);
		break;

		case Operation::stwcx_:
			if(!(opcode & 0b000000'00000'00000'00000'0000000000'1)) return Instruction(opcode);
		break;

		case Operation::divx:		case Operation::divsx:
		case Operation::dozx:		case Operation::dozi:
		case Operation::lscbxx:
		case Operation::maskgx:		case Operation::maskirx:
		case Operation::mulx:
		case Operation::rlmix:		case Operation::rribx:
		case Operation::slex:		case Operation::sleqx:		case Operation::sliqx:
		case Operation::slliqx:		case Operation::sllqx:		case Operation::slqx:
		case Operation::sraiqx:		case Operation::sraqx:
		case Operation::srex:		case Operation::sreqx:
		case Operation::sriqx:		case Operation::srliqx:
		case Operation::srlqx:		case Operation::srqx:
		case Operation::sreax:
		case Operation::addx:		case Operation::addcx:		case Operation::addex:
		case Operation::addi:		case Operation::addic:		case Operation::addic_:
		case Operation::addis:
{'fraction_non_alphanumeric': 0.12338775814508313, 'fraction_numerical': 0.12264221277864758, 'mean_word_length': 5.986458333333333, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 45, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5506839', 'n_tokens_mistral': 6310, 'n_tokens_neox': 4702, 'n_words': 978}