<commit_before>/* ###
 * IP: GHIDRA
 *
 * 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.
 */
package ghidra.program.model.lang;

import java.util.*;

import ghidra.program.model.address.Address;
import ghidra.util.Msg;

public class RegisterBuilder {

	ArrayList<Register> registerList;
	Map<String, Register> registerMap; // include aliases and case-variations
	Address contextAddress;

	public RegisterBuilder() {
		registerList = new ArrayList<>();
		registerMap = new HashMap<>();
	}

	public void addRegister(String name, String description, Address address, int numBytes,
			boolean bigEndian, int typeFlags) {
		addRegister(name, description, address, numBytes, 0, numBytes * 8, bigEndian, typeFlags);
	}

	public void addRegister(String name, String description, Address address, int numBytes,
			int leastSignificantBit, int bitLength, boolean bigEndian, int typeFlags) {

		Register register = new Register(name, description, address, numBytes, leastSignificantBit,
			bitLength, bigEndian, typeFlags);
		addRegister(register);
	}

	public void addRegister(Register register) {
		String name = register.getName();
		if (registerMap.get(name) != null) {
			Msg.error(this, "Duplicate register name: " + name);
			// TODO: should we throw exception - hopefully sleigh will prevent this condition
		}
		// Use of register alias handles case where context field is defined with different names
		for (Register reg : registerList) {
			if (reg.getAddress().equals(register.getAddress()) &&
				reg.getLeastSignificantBit() == register.getLeastSignificantBit() &&
				reg.getBitLength() == register.getBitLength()) {
				// define as register alias
				reg.addAlias(name);
				addRegisterToNameMap(name, register);
				return;
			}
		}
		if (contextAddress == null && register.isProcessorContext()) {
			contextAddress = register.getAddress();
		}
		registerList.add(register);
		addRegisterToNameMap(name, register);
	}

	private void addRegisterToNameMap(String name, Register register) {
		registerMap.put(name, register);
		registerMap.put(name.toLowerCase(), register);
		registerMap.put(name.toUpperCase(), register);
	}

	private void removeRegisterFromNameMap(String name) {
		registerMap.remove(name);
		registerMap.remove(name.toLowerCase());
		registerMap.remove(name.toUpperCase());<commit_msg>GP-38 corrected register alias bug introduced with recent change<commit_after>/* ###
 * IP: GHIDRA
 *
 * 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.
 */
package ghidra.program.model.lang;

import java.util.*;

import ghidra.program.model.address.Address;
import ghidra.util.Msg;

public class RegisterBuilder {

	ArrayList<Register> registerList;
	Map<String, Register> registerMap; // include aliases and case-variations
	Address contextAddress;

	public RegisterBuilder() {
		registerList = new ArrayList<>();
		registerMap = new HashMap<>();
	}

	public void addRegister(String name, String description, Address address, int numBytes,
			boolean bigEndian, int typeFlags) {
		addRegister(name, description, address, numBytes, 0, numBytes * 8, bigEndian, typeFlags);
	}

	public void addRegister(String name, String description, Address address, int numBytes,
			int leastSignificantBit, int bitLength, boolean bigEndian, int typeFlags) {

		Register register = new Register(name, description, address, numBytes, leastSignificantBit,
			bitLength, bigEndian, typeFlags);
		addRegister(register);
	}

	public void addRegister(Register register) {
		String name = register.getName();
		if (registerMap.get(name) != null) {
			Msg.error(this, "Duplicate register name: " + name);
			// TODO: should we throw exception - hopefully sleigh will prevent this condition
		}
		// Use of register alias handles case where context field is defined with different names
		for (Register reg : registerList) {
			if (reg.getAddress().equals(register.getAddress()) &&
				reg.getLeastSignificantBit() == register.getLeastSignificantBit() &&
				reg.getBitLength() == register.getBitLength()) {
				// define as register alias
				reg.addAlias(name);
				addRegisterToNameMap(name, reg);
				return;
			}
		}
		if (contextAddress == null && register.isProcessorContext()) {
			contextAddress = register.getAddress();
		}
		registerList.add(register);
		addRegisterToNameMap(name, register);
	}

	private void addRegisterToNameMap(String name, Register register) {
		registerMap.put(name, register);
		registerMap.put(name.toLowerCase(), register);
		registerMap.put(name.toUpperCase(), register);
	}

	private void removeRegisterFromNameMap(String name) {
		registerMap.remove(name);
		registerMap.remove(name.toLowerCase());
		registerMap.remove(name.toUpperCase());
{'fraction_non_alphanumeric': 0.10225272791270679, 'fraction_numerical': 0.0024639211545230554, 'mean_word_length': 4.626732673267327, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, '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': '7064449', 'n_tokens_mistral': 1686, 'n_tokens_neox': 1548, 'n_words': 507}