Merge remote-tracking branch 'origin/GP-1256_Dan_bitRegisters--SQUASHED' into patch

This commit is contained in:
Ryan Kurtz 2021-09-07 11:15:36 -04:00
commit e61571669f
10 changed files with 661 additions and 473 deletions

View file

@ -21,11 +21,10 @@ import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
/**
* Class to represent a processor register. To sort of handle bit registers, a
* special addressing convention is used. First the upper bit is set. Second, the
* next 3 bits are used to specify what bit position within a byte that this register
* bit exists at. Finally, the rest of the address is the address of the byte where
* the register bit lives.
* Class to represent a processor register. To sort of handle bit registers, a special addressing
* convention is used. First the upper bit is set. Second, the next 3 bits are used to specify what
* bit position within a byte that this register bit exists at. Finally, the rest of the address is
* the address of the byte where the register bit lives.
*/
public class Register implements java.io.Serializable, Comparable<Register> {
@ -61,7 +60,7 @@ public class Register implements java.io.Serializable, Comparable<Register> {
private Register baseRegister;
private String group;
/**Set of valid lane sizes**/
/** Set of valid lane sizes **/
private TreeSet<Integer> laneSizes;
/**
@ -72,10 +71,10 @@ public class Register implements java.io.Serializable, Comparable<Register> {
* @param address the address in register space of this register
* @param numBytes the size (in bytes) of this register
* @param bigEndian true if the most significant bytes are associated with the lowest register
* addresses, and false if the least significant bytes are associated with the lowest register
* addresses.
* @param typeFlags the type(s) of this Register (TYPE_NONE, TYPE_FP, TYPE_SP,
* TYPE_PC, TYPE_CONTEXT, TYPE_ZERO);)
* addresses, and false if the least significant bytes are associated with the lowest
* register addresses.
* @param typeFlags the type(s) of this Register (TYPE_NONE, TYPE_FP, TYPE_SP, TYPE_PC,
* TYPE_CONTEXT, TYPE_ZERO);)
*/
public Register(String name, String description, Address address, int numBytes,
boolean bigEndian, int typeFlags) {
@ -128,6 +127,7 @@ public class Register implements java.io.Serializable, Comparable<Register> {
/**
* Add register alias
*
* @param aliasReg
*/
void addAlias(String alias) {
@ -142,6 +142,7 @@ public class Register implements java.io.Serializable, Comparable<Register> {
/**
* Remove register alias
*
* @param alias
*/
void removeAlias(String alias) {
@ -151,9 +152,8 @@ public class Register implements java.io.Serializable, Comparable<Register> {
}
/**
* Return register aliases.
* NOTE: This is generally only supported for
* context register fields.
* Return register aliases. NOTE: This is generally only supported for context register fields.
*
* @return register aliases or null
*/
public Iterable<String> getAliases() {
@ -201,6 +201,19 @@ public class Register implements java.io.Serializable, Comparable<Register> {
return (bitLength + 7) / 8;
}
/**
* Returns the number of bytes spanned by this Register.
*
* <p>
* Compare to {{@link #getMinimumByteSize()}: Suppose a 5-bit register spans 2 bytes: 1 bit in
* the first byte, and the remaining 4 in the following byte. Its value can still be stored in 1
* byte, which is what {@link #getMinimumByteSize()} returns; however, its storage still spans 2
* bytes of the base register, which is what this method returns.
*/
public int getNumBytes() {
return numBytes;
}
/**
* Returns the offset into the register space for this register
*/
@ -210,6 +223,7 @@ public class Register implements java.io.Serializable, Comparable<Register> {
/**
* Returns the bit offset from the register address for this register.
*
* @return the bit offset from the register address for this register.
*/
public int getLeastSignificantBit() {
@ -224,8 +238,7 @@ public class Register implements java.io.Serializable, Comparable<Register> {
}
/**
* Returns true for a register whose context value should
* follow the disassembly flow.
* Returns true for a register whose context value should follow the disassembly flow.
*/
public boolean followsFlow() {
return (typeFlags & TYPE_DOES_NOT_FOLLOW_FLOW) == 0;
@ -335,8 +348,8 @@ public class Register implements java.io.Serializable, Comparable<Register> {
}
/**
* Returns list of children registers sorted by
* lest-significant bit-offset within this register.
* Returns list of children registers sorted by lest-significant bit-offset within this
* register.
*/
public List<Register> getChildRegisters() {
return new ArrayList<>(childRegisters);
@ -400,6 +413,7 @@ public class Register implements java.io.Serializable, Comparable<Register> {
/**
* Returns the mask that indicates which bits in the base register apply to this register.
*
* @return the mask that indicates which bits in the base register apply to this register
*/
public byte[] getBaseMask() {
@ -445,11 +459,11 @@ public class Register implements java.io.Serializable, Comparable<Register> {
}
/**
* Determines if reg is contained within this register.
* Method does not work for bit registers (e.g., context-bits)
* Determines if reg is contained within this register. Method does not work for bit registers
* (e.g., context-bits)
*
* @param reg another register
* @return true if reg equals this register or is contained
* within it.
* @return true if reg equals this register or is contained within it.
*/
public boolean contains(Register reg) {
if (equals(reg)) {
@ -472,8 +486,9 @@ public class Register implements java.io.Serializable, Comparable<Register> {
/**
* Returns true if this is a vector register
* @return true precisely when {@code this} is a full vector register (i.e., a register that can be
* used as input or output for a SIMD operation).
*
* @return true precisely when {@code this} is a full vector register (i.e., a register that can
* be used as input or output for a SIMD operation).
*/
public boolean isVectorRegister() {
return (typeFlags & TYPE_VECTOR) != 0;
@ -481,8 +496,10 @@ public class Register implements java.io.Serializable, Comparable<Register> {
/**
* Determines whether {@code laneSizeInBytes} is a valid lane size for this register.
*
* @param laneSizeInBytes lane size to check, measured in bytes
* @return true precisely when {@code this} is a vector register and {@code laneSizeInBytes} is a valid lane size.
* @return true precisely when {@code this} is a vector register and {@code laneSizeInBytes} is
* a valid lane size.
*/
public boolean isValidLaneSize(int laneSizeInBytes) {
if (!isVectorRegister()) {
@ -496,7 +513,9 @@ public class Register implements java.io.Serializable, Comparable<Register> {
/**
* Returns the sorted array of lane sizes for this register, measured in bytes.
* @return array of lane sizes, or {@code null} if {@code this} is not a vector register or no lane sizes have been set.
*
* @return array of lane sizes, or {@code null} if {@code this} is not a vector register or no
* lane sizes have been set.
*/
public int[] getLaneSizes() {
if (laneSizes == null) {
@ -512,9 +531,10 @@ public class Register implements java.io.Serializable, Comparable<Register> {
/**
* Adds a lane size.
*
* @param laneSizeInBytes lane size to add
* @throws UnsupportedOperationException if register is unable to support the definition of
* lanes.
* @throws UnsupportedOperationException if register is unable to support the definition of
* lanes.
* @throws IllegalArgumentException if {@code laneSizeInBytes} is invalid
*/
void addLaneSize(int laneSizeInBytes) {