diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Register.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Register.java index fab3b05c2e1..2736eaa3e9b 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Register.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/Register.java @@ -4,9 +4,9 @@ * 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. @@ -64,8 +64,8 @@ public class Register implements java.io.Serializable, Comparable { private Register baseRegister; private String group; - /** Set of valid lane sizes **/ - private TreeSet laneSizes; + /** Bit vector of valid lane sizes **/ + private long laneSizes; /** * Constructs a new Register object. @@ -101,6 +101,7 @@ public Register(String name, String description, Address address, int numBytes, this.typeFlags = typeFlags; this.bigEndian = bigEndian; this.bitLength = bitLength; + this.laneSizes = 0; int leastSigByte = leastSignificantBit / 8; int mostSigByte = (leastSignificantBit + bitLength - 1) / 8; @@ -509,10 +510,10 @@ public boolean isValidLaneSize(int laneSizeInBytes) { if (!isVectorRegister()) { return false; } - if (laneSizes == null) { + if (laneSizeInBytes > 64 || laneSizeInBytes < 1) { return false; } - return laneSizes.contains(laneSizeInBytes); + return (((1L << (laneSizeInBytes - 1)) & laneSizes) != 0); } /** @@ -522,13 +523,19 @@ public boolean isValidLaneSize(int laneSizeInBytes) { * lane sizes have been set. */ public int[] getLaneSizes() { - if (laneSizes == null) { + if (laneSizes == 0) { return null; } - int[] sizes = new int[laneSizes.size()]; + int[] sizes = new int[Long.bitCount(laneSizes)]; int index = 0; - for (int size : laneSizes) { - sizes[index++] = size; + int size = 1; + long tmp = laneSizes; + while (tmp != 0) { + if ((tmp & 1) != 0) { + sizes[index++] = size; + } + tmp >>= 1; + size += 1; } return sizes; } @@ -546,16 +553,13 @@ void addLaneSize(int laneSizeInBytes) { throw new UnsupportedOperationException( "Register " + getName() + " does not support lanes"); } - if (laneSizeInBytes <= 0 || laneSizeInBytes >= numBytes || + if (laneSizeInBytes <= 0 || laneSizeInBytes >= numBytes || laneSizeInBytes > 64 || (numBytes % laneSizeInBytes) != 0) { throw new IllegalArgumentException( "Invalid lane size: " + laneSizeInBytes + " for register " + getName()); } - if (laneSizes == null) { - laneSizes = new TreeSet<>(); - } typeFlags |= TYPE_VECTOR; - laneSizes.add(laneSizeInBytes); + laneSizes |= (1L << (laneSizeInBytes - 1)); } } diff --git a/Ghidra/Processors/x86/data/languages/x86-64.pspec b/Ghidra/Processors/x86/data/languages/x86-64.pspec index 08cefc96c78..45df40cdb84 100644 --- a/Ghidra/Processors/x86/data/languages/x86-64.pspec +++ b/Ghidra/Processors/x86/data/languages/x86-64.pspec @@ -76,6 +76,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -92,22 +124,54 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/x86/data/languages/x86.pspec b/Ghidra/Processors/x86/data/languages/x86.pspec index 595d1e2da45..b473a93bec0 100644 --- a/Ghidra/Processors/x86/data/languages/x86.pspec +++ b/Ghidra/Processors/x86/data/languages/x86.pspec @@ -60,38 +60,102 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +