mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
Merge remote-tracking branch 'origin/GP-1255_Dan_wow64--SQUASHED'
This commit is contained in:
commit
03b0decf4f
20 changed files with 840 additions and 509 deletions
|
@ -344,6 +344,11 @@ public class DebuggerListingProvider extends CodeViewerProvider {
|
||||||
return current.isAliveAndPresent();
|
return current.isAliveAndPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDynamicListing() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWindowGroup() {
|
public String getWindowGroup() {
|
||||||
//TODO: Overriding this to align disconnected providers
|
//TODO: Overriding this to align disconnected providers
|
||||||
|
|
|
@ -71,20 +71,15 @@ public class DbgengX64DisassemblyInject implements DisassemblyInject {
|
||||||
}
|
}
|
||||||
Mode mode = modes.iterator().next();
|
Mode mode = modes.iterator().next();
|
||||||
Language lang = trace.getBaseLanguage();
|
Language lang = trace.getBaseLanguage();
|
||||||
Register addrsizeReg = lang.getRegister("addrsize");
|
Register longModeReg = lang.getRegister("longMode");
|
||||||
Register opsizeReg = lang.getRegister("opsize");
|
|
||||||
ProgramContextImpl context = new ProgramContextImpl(lang);
|
ProgramContextImpl context = new ProgramContextImpl(lang);
|
||||||
lang.applyContextSettings(context);
|
lang.applyContextSettings(context);
|
||||||
RegisterValue ctxVal = context.getDisassemblyContext(first.getMinAddress());
|
RegisterValue ctxVal = new RegisterValue(context.getBaseContextRegister());
|
||||||
if (mode == Mode.X64) {
|
if (mode == Mode.X64) {
|
||||||
command.setInitialContext(ctxVal
|
command.setInitialContext(ctxVal.assign(longModeReg, BigInteger.ONE));
|
||||||
.assign(addrsizeReg, BigInteger.TWO)
|
|
||||||
.assign(opsizeReg, BigInteger.TWO));
|
|
||||||
}
|
}
|
||||||
else if (mode == Mode.X86) {
|
else if (mode == Mode.X86) {
|
||||||
command.setInitialContext(ctxVal
|
command.setInitialContext(ctxVal.assign(longModeReg, BigInteger.ZERO));
|
||||||
.assign(addrsizeReg, BigInteger.ONE)
|
|
||||||
.assign(opsizeReg, BigInteger.ONE));
|
|
||||||
}
|
}
|
||||||
// Shouldn't ever get anything else.
|
// Shouldn't ever get anything else.
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,7 @@ import org.junit.*;
|
||||||
|
|
||||||
import com.google.common.collect.Range;
|
import com.google.common.collect.Range;
|
||||||
|
|
||||||
import ghidra.app.cmd.disassemble.ArmDisassembleCommand;
|
import ghidra.app.cmd.disassemble.*;
|
||||||
import ghidra.app.cmd.disassemble.MipsDisassembleCommand;
|
|
||||||
import ghidra.program.database.ProgramBuilder;
|
import ghidra.program.database.ProgramBuilder;
|
||||||
import ghidra.program.disassemble.Disassembler;
|
import ghidra.program.disassemble.Disassembler;
|
||||||
import ghidra.program.model.address.AddressOverflowException;
|
import ghidra.program.model.address.AddressOverflowException;
|
||||||
|
@ -215,4 +214,74 @@ public class DBTraceDisassemblerIntegrationTest extends AbstractGhidraHeadlessIn
|
||||||
assertEquals("_nop", cu2.toString());
|
assertEquals("_nop", cu2.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestLanguage(ProgramBuilder._X64)
|
||||||
|
public void test64BitX86DBTrace() throws Exception {
|
||||||
|
try (UndoableTransaction tid = b.startTransaction()) {
|
||||||
|
DBTraceMemoryManager memory = b.trace.getMemoryManager();
|
||||||
|
memory.createRegion(".text", 0, b.range(0x00400000, 0x00400fff));
|
||||||
|
memory.putBytes(0, b.addr(0x00400000), b.buf(
|
||||||
|
// MOV RCX,RAX; Same encoding as DEC EAX; MOV ECX,EAX outside long mode
|
||||||
|
0x48, 0x89, 0xc1));
|
||||||
|
|
||||||
|
AddressSet restricted = new AddressSet(b.addr(0x00400000), b.addr(0x00400002));
|
||||||
|
X86_64DisassembleCommand x86Dis =
|
||||||
|
new X86_64DisassembleCommand(b.addr(0x00400000), restricted, false);
|
||||||
|
x86Dis.applyTo(b.trace.getFixedProgramView(0), TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
DBTraceCodeUnitsMemoryView cuManager = b.trace.getCodeManager().codeUnits();
|
||||||
|
CodeUnit cu1 = cuManager.getAt(0, b.addr(0x00400000));
|
||||||
|
assertEquals("MOV RCX,RAX", cu1.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestLanguage(ProgramBuilder._X64)
|
||||||
|
public void test32BitX64CompatDBTrace() throws Exception {
|
||||||
|
try (UndoableTransaction tid = b.startTransaction()) {
|
||||||
|
DBTraceMemoryManager memory = b.trace.getMemoryManager();
|
||||||
|
memory.createRegion(".text", 0, b.range(0x00400000, 0x00400fff));
|
||||||
|
memory.putBytes(0, b.addr(0x00400000), b.buf(
|
||||||
|
// DEC EAX; but REX.W if context not heeded
|
||||||
|
0x48,
|
||||||
|
// MOV ECX,EAX
|
||||||
|
0x89, 0xc1));
|
||||||
|
|
||||||
|
AddressSet restricted = new AddressSet(b.addr(0x00400000), b.addr(0x00400002));
|
||||||
|
X86_64DisassembleCommand x86Dis =
|
||||||
|
new X86_64DisassembleCommand(b.addr(0x00400000), restricted, true);
|
||||||
|
x86Dis.applyTo(b.trace.getFixedProgramView(0), TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
DBTraceCodeUnitsMemoryView cuManager = b.trace.getCodeManager().codeUnits();
|
||||||
|
CodeUnit cu1 = cuManager.getAt(0, b.addr(0x00400000));
|
||||||
|
assertEquals("DEC EAX", cu1.toString());
|
||||||
|
CodeUnit cu2 = cuManager.getAt(0, b.addr(0x00400001));
|
||||||
|
assertEquals("MOV ECX,EAX", cu2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestLanguage(ProgramBuilder._X86)
|
||||||
|
public void test32BitX86DBTrace() throws Exception {
|
||||||
|
try (UndoableTransaction tid = b.startTransaction()) {
|
||||||
|
DBTraceMemoryManager memory = b.trace.getMemoryManager();
|
||||||
|
memory.createRegion(".text", 0, b.range(0x00400000, 0x00400fff));
|
||||||
|
memory.putBytes(0, b.addr(0x00400000), b.buf(
|
||||||
|
// DEC EAX
|
||||||
|
0x48,
|
||||||
|
// MOV ECX,EAX
|
||||||
|
0x89, 0xc1));
|
||||||
|
|
||||||
|
AddressSet restricted = new AddressSet(b.addr(0x00400000), b.addr(0x00400002));
|
||||||
|
DisassembleCommand dis =
|
||||||
|
new DisassembleCommand(b.addr(0x00400000), restricted, true);
|
||||||
|
dis.applyTo(b.trace.getFixedProgramView(0), TaskMonitor.DUMMY);
|
||||||
|
|
||||||
|
DBTraceCodeUnitsMemoryView cuManager = b.trace.getCodeManager().codeUnits();
|
||||||
|
CodeUnit cu1 = cuManager.getAt(0, b.addr(0x00400000));
|
||||||
|
assertEquals("DEC EAX", cu1.toString());
|
||||||
|
CodeUnit cu2 = cuManager.getAt(0, b.addr(0x00400001));
|
||||||
|
assertEquals("MOV ECX,EAX", cu2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,7 @@ import ghidra.framework.cmd.BackgroundCommand;
|
||||||
import ghidra.framework.model.DomainObject;
|
import ghidra.framework.model.DomainObject;
|
||||||
import ghidra.program.disassemble.*;
|
import ghidra.program.disassemble.*;
|
||||||
import ghidra.program.model.address.*;
|
import ghidra.program.model.address.*;
|
||||||
import ghidra.program.model.lang.Register;
|
import ghidra.program.model.lang.*;
|
||||||
import ghidra.program.model.lang.RegisterValue;
|
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.mem.Memory;
|
import ghidra.program.model.mem.Memory;
|
||||||
import ghidra.program.model.mem.MemoryBlock;
|
import ghidra.program.model.mem.MemoryBlock;
|
||||||
|
@ -46,14 +45,15 @@ public class DisassembleCommand extends BackgroundCommand {
|
||||||
|
|
||||||
private int alignment; // required instruction alignment for the last doDisassembly
|
private int alignment; // required instruction alignment for the last doDisassembly
|
||||||
protected boolean disassemblyPerformed; // if true don't report start problems
|
protected boolean disassemblyPerformed; // if true don't report start problems
|
||||||
|
protected String languageError; // non-null to indicate unsupported language
|
||||||
protected boolean unalignedStart;
|
protected boolean unalignedStart;
|
||||||
protected boolean nonExecutableStart;
|
protected boolean nonExecutableStart;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for DisassembleCommand.
|
* Constructor for DisassembleCommand.
|
||||||
|
*
|
||||||
* @param start Address to start disassembly.
|
* @param start Address to start disassembly.
|
||||||
* @param restrictedSet addresses that can be disassembled.
|
* @param restrictedSet addresses that can be disassembled. a null set implies no restrictions
|
||||||
* a null set implies no restrictions
|
|
||||||
* @param followFlow true means the disassembly should follow flow
|
* @param followFlow true means the disassembly should follow flow
|
||||||
*/
|
*/
|
||||||
public DisassembleCommand(Address start, AddressSetView restrictedSet, boolean followFlow) {
|
public DisassembleCommand(Address start, AddressSetView restrictedSet, boolean followFlow) {
|
||||||
|
@ -63,10 +63,10 @@ public class DisassembleCommand extends BackgroundCommand {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for DisassembleCommand.
|
* Constructor for DisassembleCommand.
|
||||||
* @param startSet set of addresses to be the start of a disassembly. The
|
*
|
||||||
* Command object will attempt to start a disassembly at each address in this set.
|
* @param startSet set of addresses to be the start of a disassembly. The Command object will
|
||||||
* @param restrictedSet addresses that can be disassembled.
|
* attempt to start a disassembly at each address in this set.
|
||||||
* a null set implies no restrictions
|
* @param restrictedSet addresses that can be disassembled. a null set implies no restrictions
|
||||||
*/
|
*/
|
||||||
public DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet) {
|
public DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet) {
|
||||||
this(startSet, restrictedSet, true);
|
this(startSet, restrictedSet, true);
|
||||||
|
@ -74,10 +74,10 @@ public class DisassembleCommand extends BackgroundCommand {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for DisassembleCommand.
|
* Constructor for DisassembleCommand.
|
||||||
* @param startSet set of addresses to be the start of a disassembly. The
|
*
|
||||||
* Command object will attempt to start a disassembly at each address in this set.
|
* @param startSet set of addresses to be the start of a disassembly. The Command object will
|
||||||
* @param restrictedSet addresses that can be disassembled.
|
* attempt to start a disassembly at each address in this set.
|
||||||
* a null set implies no restrictions
|
* @param restrictedSet addresses that can be disassembled. a null set implies no restrictions
|
||||||
*/
|
*/
|
||||||
public DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet,
|
public DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet,
|
||||||
boolean followFlow) {
|
boolean followFlow) {
|
||||||
|
@ -93,11 +93,12 @@ public class DisassembleCommand extends BackgroundCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows the disassembler context to be seeded for the various disassembly start
|
* Allows the disassembler context to be seeded for the various disassembly start points which
|
||||||
* points which may be encountered using the future flow state of the specified seedContext.
|
* may be encountered using the future flow state of the specified seedContext. Any initial
|
||||||
* Any initial context set via the {@link #setInitialContext(RegisterValue)} method will take
|
* context set via the {@link #setInitialContext(RegisterValue)} method will take precedence
|
||||||
* precedence when combined with any seed values.
|
* when combined with any seed values. The seedContext should remain unchanged while
|
||||||
* The seedContext should remain unchanged while disassembler command is actively running.
|
* disassembler command is actively running.
|
||||||
|
*
|
||||||
* @param seedContext seed context or null
|
* @param seedContext seed context or null
|
||||||
*/
|
*/
|
||||||
public void setSeedContext(DisassemblerContextImpl seedContext) {
|
public void setSeedContext(DisassemblerContextImpl seedContext) {
|
||||||
|
@ -107,9 +108,9 @@ public class DisassembleCommand extends BackgroundCommand {
|
||||||
/**
|
/**
|
||||||
* Allows a specified initial context to be used at all start points. This value will take
|
* Allows a specified initial context to be used at all start points. This value will take
|
||||||
* precedence when combined with any individual seed context values specified by the
|
* precedence when combined with any individual seed context values specified by the
|
||||||
* {@link #setSeedContext(DisassemblerContextImpl)} method.
|
* {@link #setSeedContext(DisassemblerContextImpl)} method. The defaultSeedContext should remain
|
||||||
* The defaultSeedContext should remain unchanged while disassembler command
|
* unchanged while disassembler command is actively running.
|
||||||
* is actively running.
|
*
|
||||||
* @param initialContextValue the initial context value to set or null to clear it
|
* @param initialContextValue the initial context value to set or null to clear it
|
||||||
*/
|
*/
|
||||||
public void setInitialContext(RegisterValue initialContextValue) {
|
public void setInitialContext(RegisterValue initialContextValue) {
|
||||||
|
@ -121,8 +122,9 @@ public class DisassembleCommand extends BackgroundCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set code analysis enablement. By default new instructions will be
|
* Set code analysis enablement. By default new instructions will be submitted for
|
||||||
* submitted for auto-analysis.
|
* auto-analysis.
|
||||||
|
*
|
||||||
* @param enable
|
* @param enable
|
||||||
*/
|
*/
|
||||||
public void enableCodeAnalysis(boolean enable) {
|
public void enableCodeAnalysis(boolean enable) {
|
||||||
|
@ -134,6 +136,9 @@ public class DisassembleCommand extends BackgroundCommand {
|
||||||
if (disassemblyPerformed) {
|
if (disassemblyPerformed) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (languageError != null) {
|
||||||
|
return "The program's language is not supported: " + languageError;
|
||||||
|
}
|
||||||
if (nonExecutableStart) {
|
if (nonExecutableStart) {
|
||||||
return "Disassembly of non-executable memory is disabled";
|
return "Disassembly of non-executable memory is disabled";
|
||||||
}
|
}
|
||||||
|
@ -335,16 +340,17 @@ public class DisassembleCommand extends BackgroundCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if intermediate analysis is required to reduce the risk of disassembling
|
* Determine if intermediate analysis is required to reduce the risk of disassembling data
|
||||||
* data regions when performing static disassembly over a contiguous range if
|
* regions when performing static disassembly over a contiguous range if addresses. This method
|
||||||
* addresses. This method attemps to identify this situation by checking the first
|
* attemps to identify this situation by checking the first range of disassembledSet against the
|
||||||
* range of disassembledSet against the startSet. Analysis will be triggered if
|
* startSet. Analysis will be triggered if startSet contains both the max address of the first
|
||||||
* startSet contains both the max address of the first range of disassembledSet
|
* range of disassembledSet (M where M=disassembledSet.firstRange().getMaxAddress()) and the
|
||||||
* (M where M=disassembledSet.firstRange().getMaxAddress()) and the next address
|
* next address (M.next()) which will be the next seed point.
|
||||||
* (M.next()) which will be the next seed point.
|
*
|
||||||
* @param mgr auto analysis manager or null if analysis disabled
|
* @param mgr auto analysis manager or null if analysis disabled
|
||||||
* @param startSet disassembly seed points (prior to removing disassembledSet)
|
* @param startSet disassembly seed points (prior to removing disassembledSet)
|
||||||
* @param disassembledSet last set of disassembled addresses using startSet min-address as seed point
|
* @param disassembledSet last set of disassembled addresses using startSet min-address as seed
|
||||||
|
* point
|
||||||
*/
|
*/
|
||||||
private static void analyzeIfNeeded(AutoAnalysisManager mgr, AddressSetView startSet,
|
private static void analyzeIfNeeded(AutoAnalysisManager mgr, AddressSetView startSet,
|
||||||
AddressSetView disassembledSet, TaskMonitor monitor) {
|
AddressSetView disassembledSet, TaskMonitor monitor) {
|
||||||
|
@ -366,6 +372,7 @@ public class DisassembleCommand extends BackgroundCommand {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an address set of all instructions that were disassembled.
|
* Returns an address set of all instructions that were disassembled.
|
||||||
|
*
|
||||||
* @return an address set of all instructions that were disassembled
|
* @return an address set of all instructions that were disassembled
|
||||||
*/
|
*/
|
||||||
public AddressSet getDisassembledAddressSet() {
|
public AddressSet getDisassembledAddressSet() {
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
/* ###
|
||||||
|
* 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.app.cmd.disassemble;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import javax.help.UnsupportedOperationException;
|
||||||
|
|
||||||
|
import ghidra.framework.model.DomainObject;
|
||||||
|
import ghidra.program.disassemble.DisassemblerContextImpl;
|
||||||
|
import ghidra.program.model.address.*;
|
||||||
|
import ghidra.program.model.lang.*;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
import ghidra.program.model.listing.ProgramContext;
|
||||||
|
import ghidra.util.exception.CancelledException;
|
||||||
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command object for performing 64-/32-bit x86 disassembly
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This generally only comes up when debugging, since there can be multiple images loaded by an
|
||||||
|
* x86-64 target. For WoW64, the images may be mixed. Thus, this command allows you to disassemble
|
||||||
|
* 64-bit or 32-bit instructions whenever the language is set to 64-bit x86.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* <b>WARNING:</b> If used in static programs, i.e., not debug traces, there are some potential
|
||||||
|
* remaining issues, particularly dealing with stored context and follow-on disassembly -- typically
|
||||||
|
* called for by the analyzers. In most cases, this does not matter, since mixed 64- and 32-bit code
|
||||||
|
* in a single image is likely a niche case and can be handled via careful commands from the user.
|
||||||
|
* Nevertheless, TODO: Rework x86-64 analyzers to call the correct mode of disassembly.
|
||||||
|
*/
|
||||||
|
public class X86_64DisassembleCommand extends DisassembleCommand {
|
||||||
|
|
||||||
|
private final boolean size32Mode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for X86_64DisassembleCommand.
|
||||||
|
*
|
||||||
|
* @param startSet set of addresses to be the start of disassembly. The Command object will
|
||||||
|
* attempt to start a disassembly at each address in this set.
|
||||||
|
* @param restrictedSet addresses that can be disassembled. a null set implies no restrictions.
|
||||||
|
* @param size32Mode pass true if disassembling in 32-bit compatibility mode, otherwise normal
|
||||||
|
* 64-bit disassembly will be performed.
|
||||||
|
*/
|
||||||
|
public X86_64DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet,
|
||||||
|
boolean size32Mode) {
|
||||||
|
super(startSet, restrictedSet, true);
|
||||||
|
this.size32Mode = size32Mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for X86_64DisassembleCommand.
|
||||||
|
*
|
||||||
|
* @param start address to be the start of a disassembly.
|
||||||
|
* @param restrictedSet addresses that can be disassembled. a null set implies no restrictions.
|
||||||
|
* @param size32Mode pass true if disassembling in 32-bit compatibility mode, otherwise normal
|
||||||
|
* 64-bit disassembly will be performed.
|
||||||
|
*/
|
||||||
|
public X86_64DisassembleCommand(Address start, AddressSetView restrictedSet,
|
||||||
|
boolean size32Mode) {
|
||||||
|
super(start, restrictedSet, true);
|
||||||
|
this.size32Mode = size32Mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Disassemble " + (size32Mode ? "32" : "64") + "-bit x86";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSeedContext(DisassemblerContextImpl seedContext) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInitialContext(RegisterValue initialContextValue) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AddressSet alignSet(int alignment, AddressSetView set)
|
||||||
|
throws CancelledException {
|
||||||
|
AddressSet result = new AddressSet();
|
||||||
|
for (AddressRange range : set) {
|
||||||
|
Address min = range.getMinAddress();
|
||||||
|
long minOfffset = min.getOffset();
|
||||||
|
if (minOfffset != min.getOffset()) {
|
||||||
|
min = min.getNewAddress(minOfffset);
|
||||||
|
}
|
||||||
|
Address max = range.getMaxAddress();
|
||||||
|
long maxOffset = max.getOffset();
|
||||||
|
if (maxOffset < minOfffset) {
|
||||||
|
// skip short unaligned range
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (maxOffset != max.getOffset()) {
|
||||||
|
max = max.getNewAddress(maxOffset);
|
||||||
|
}
|
||||||
|
result.addRange(min, max);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
synchronized public boolean applyTo(DomainObject obj, TaskMonitor monitor) {
|
||||||
|
Program program = (Program) obj;
|
||||||
|
|
||||||
|
disassemblyPerformed = false;
|
||||||
|
unalignedStart = false;
|
||||||
|
|
||||||
|
// get the longMode register and set accordingly
|
||||||
|
ProgramContext context = program.getProgramContext();
|
||||||
|
Register longModeReg = context.getRegister("longMode");
|
||||||
|
|
||||||
|
// Indicates we're not x86-64, or the spec has changed
|
||||||
|
if (longModeReg == null) {
|
||||||
|
languageError = "Requires x86:LE:64:default";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RegisterValue ctx = new RegisterValue(context.getBaseContextRegister())
|
||||||
|
.assign(longModeReg, size32Mode ? BigInteger.ZERO : BigInteger.ONE);
|
||||||
|
|
||||||
|
super.setInitialContext(ctx);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (startSet != null) {
|
||||||
|
// This is identity, no?
|
||||||
|
AddressSet alignedSet = alignSet(1, startSet);
|
||||||
|
if (alignedSet.isEmpty()) {
|
||||||
|
unalignedStart = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
startSet = program.getListing().getUndefinedRanges(alignedSet, true, monitor);
|
||||||
|
if (startSet.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (CancelledException e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return doDisassembly(monitor, program, 1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,22 +34,19 @@ import ghidra.program.util.ProgramLocation;
|
||||||
import ghidra.program.util.ProgramSelection;
|
import ghidra.program.util.ProgramSelection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <CODE>DisassemblerPlugin</CODE> provides functionality for dynamic disassembly,
|
* <CODE>DisassemblerPlugin</CODE> provides functionality for dynamic disassembly, static
|
||||||
* static disassembly.<BR>
|
* disassembly.<BR>
|
||||||
* In dynamic disassembly disassembling begins from the
|
* In dynamic disassembly disassembling begins from the selected addresses or if there is no
|
||||||
* selected addresses or if there is no selection then at the address of the
|
* selection then at the address of the current cursor location and attempts to continue
|
||||||
* current cursor location and attempts to continue disassembling
|
* disassembling through fallthroughs and along all flows from a disassembled instruction. For
|
||||||
* through fallthroughs and along all flows from a disassembled instruction.
|
* instance, if a jump instruction is disassembled then the address being jumped to will be
|
||||||
* For instance, if a jump instruction is disassembled then the address being
|
* disassembled. The dynamic disassembly will also follow data pointers to addresses containing
|
||||||
* jumped to will be disassembled. The dynamic disassembly will also follow
|
* undefined data, which is then disassembled.<BR>
|
||||||
* data pointers to addresses containing undefined data, which is then
|
* In static disassembly a range or set of ranges is given and disassembly is attempted on each
|
||||||
* disassembled.<BR>
|
* range. Any defined code in the ranges before the static disassembly are first removed.<BR>
|
||||||
* In static disassembly a range or set of ranges
|
|
||||||
* is given and disassembly is attempted on each range. Any defined code in the
|
|
||||||
* ranges before the static disassembly are first removed.<BR>
|
|
||||||
* <P>
|
* <P>
|
||||||
* <CODE>DisassemblerPlugin</CODE> provides access to its functions as a service
|
* <CODE>DisassemblerPlugin</CODE> provides access to its functions as a service that another plugin
|
||||||
* that another plugin may use and through the popup menu to the user.
|
* may use and through the popup menu to the user.
|
||||||
*/
|
*/
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
@PluginInfo(
|
@PluginInfo(
|
||||||
|
@ -89,6 +86,8 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
private DockingAction mips16DisassembleAction;
|
private DockingAction mips16DisassembleAction;
|
||||||
private DockingAction ppcDisassembleAction;
|
private DockingAction ppcDisassembleAction;
|
||||||
private DockingAction ppcVleDisassembleAction;
|
private DockingAction ppcVleDisassembleAction;
|
||||||
|
private DockingAction x86_64DisassembleAction;
|
||||||
|
private DockingAction x86_32DisassembleAction;
|
||||||
private DockingAction setFlowOverrideAction;
|
private DockingAction setFlowOverrideAction;
|
||||||
|
|
||||||
/** Dialog for obtaining the processor state to be used for disassembling. */
|
/** Dialog for obtaining the processor state to be used for disassembling. */
|
||||||
|
@ -128,8 +127,7 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance of the plugin giving it the tool that
|
* Creates a new instance of the plugin giving it the tool that it will work in.
|
||||||
* it will work in.
|
|
||||||
*/
|
*/
|
||||||
public DisassemblerPlugin(PluginTool tool) {
|
public DisassemblerPlugin(PluginTool tool) {
|
||||||
super(tool);
|
super(tool);
|
||||||
|
@ -177,6 +175,8 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
mips16DisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, true);
|
mips16DisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, true);
|
||||||
ppcDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, false);
|
ppcDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, false);
|
||||||
ppcVleDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, true);
|
ppcVleDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, true);
|
||||||
|
x86_64DisassembleAction = new X86_64DisassembleAction(this, GROUP_NAME, false);
|
||||||
|
x86_32DisassembleAction = new X86_64DisassembleAction(this, GROUP_NAME, true);
|
||||||
setFlowOverrideAction = new SetFlowOverrideAction(this, GROUP_NAME);
|
setFlowOverrideAction = new SetFlowOverrideAction(this, GROUP_NAME);
|
||||||
|
|
||||||
tool.addAction(disassembleAction);
|
tool.addAction(disassembleAction);
|
||||||
|
@ -190,6 +190,8 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
tool.addAction(mips16DisassembleAction);
|
tool.addAction(mips16DisassembleAction);
|
||||||
tool.addAction(ppcDisassembleAction);
|
tool.addAction(ppcDisassembleAction);
|
||||||
tool.addAction(ppcVleDisassembleAction);
|
tool.addAction(ppcVleDisassembleAction);
|
||||||
|
tool.addAction(x86_64DisassembleAction);
|
||||||
|
tool.addAction(x86_32DisassembleAction);
|
||||||
tool.addAction(contextAction);
|
tool.addAction(contextAction);
|
||||||
tool.addAction(setFlowOverrideAction);
|
tool.addAction(setFlowOverrideAction);
|
||||||
}
|
}
|
||||||
|
@ -244,7 +246,8 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
try {
|
try {
|
||||||
currentProgram.getMemory().getByte(addr);
|
currentProgram.getMemory().getByte(addr);
|
||||||
AddressSetView restrictedSet = null;
|
AddressSetView restrictedSet = null;
|
||||||
if (isDynamicListing) {
|
// I believe this is deprecated
|
||||||
|
/*if (isDynamicListing) {
|
||||||
// TODO: should we have option to control restricted range?
|
// TODO: should we have option to control restricted range?
|
||||||
Address min, max;
|
Address min, max;
|
||||||
try {
|
try {
|
||||||
|
@ -260,7 +263,7 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
max = addr.getAddressSpace().getMaxAddress();
|
max = addr.getAddressSpace().getMaxAddress();
|
||||||
}
|
}
|
||||||
restrictedSet = new AddressSet(min, max);
|
restrictedSet = new AddressSet(min, max);
|
||||||
}
|
}*/
|
||||||
cmd = new DisassembleCommand(addr, restrictedSet, true);
|
cmd = new DisassembleCommand(addr, restrictedSet, true);
|
||||||
}
|
}
|
||||||
catch (MemoryAccessException e) {
|
catch (MemoryAccessException e) {
|
||||||
|
@ -409,4 +412,27 @@ public class DisassemblerPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void disassembleX86_64Callback(ListingActionContext context, boolean size32Mode) {
|
||||||
|
ProgramSelection currentSelection = context.getSelection();
|
||||||
|
ProgramLocation currentLocation = context.getLocation();
|
||||||
|
Program currentProgram = context.getProgram();
|
||||||
|
final X86_64DisassembleCommand cmd;
|
||||||
|
|
||||||
|
if ((currentSelection != null) && (!currentSelection.isEmpty())) {
|
||||||
|
cmd = new X86_64DisassembleCommand(currentSelection, null, size32Mode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Address addr = currentLocation.getAddress();
|
||||||
|
try {
|
||||||
|
currentProgram.getMemory().getByte(addr);
|
||||||
|
cmd = new X86_64DisassembleCommand(addr, null, size32Mode);
|
||||||
|
}
|
||||||
|
catch (MemoryAccessException e) {
|
||||||
|
tool.setStatusInfo("Can't disassemble uninitialized memory!", true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tool.executeBackgroundCommand(cmd, currentProgram);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/* ###
|
||||||
|
* 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.app.plugin.core.disassembler;
|
||||||
|
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
|
import docking.action.KeyBindingData;
|
||||||
|
import docking.action.MenuData;
|
||||||
|
import ghidra.app.context.ListingActionContext;
|
||||||
|
import ghidra.app.context.ListingContextAction;
|
||||||
|
import ghidra.app.plugin.core.codebrowser.CodeViewerActionContext;
|
||||||
|
import ghidra.program.model.address.Address;
|
||||||
|
import ghidra.program.model.lang.Language;
|
||||||
|
import ghidra.program.model.lang.Processor;
|
||||||
|
import ghidra.program.model.listing.Program;
|
||||||
|
|
||||||
|
public class X86_64DisassembleAction extends ListingContextAction {
|
||||||
|
private final DisassemblerPlugin plugin;
|
||||||
|
private final boolean disassemble32Bit;
|
||||||
|
|
||||||
|
public X86_64DisassembleAction(DisassemblerPlugin plugin, String groupName,
|
||||||
|
boolean disassemble32Bit) {
|
||||||
|
super("Disassemble " + (disassemble32Bit ? "32" : "64") + "-bit x86", plugin.getName());
|
||||||
|
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.disassemble32Bit = disassemble32Bit;
|
||||||
|
|
||||||
|
setPopupMenuData(new MenuData(new String[] { getName() }, null, groupName));
|
||||||
|
|
||||||
|
int keyEvent = (disassemble32Bit ? KeyEvent.VK_F12 : KeyEvent.VK_F11);
|
||||||
|
setKeyBindingData(new KeyBindingData(keyEvent, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ListingActionContext context) {
|
||||||
|
plugin.disassembleX86_64Callback(context, disassemble32Bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabledForContext(ListingActionContext context) {
|
||||||
|
// STOPGAP: Disable these in the static context
|
||||||
|
if (!(context instanceof CodeViewerActionContext)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address address = context.getAddress();
|
||||||
|
if (address == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Program program = context.getProgram();
|
||||||
|
Language lang = program.getLanguage();
|
||||||
|
Processor proc = lang.getProcessor();
|
||||||
|
/*
|
||||||
|
* Action only intended for use where 64-bit x86 is available. I'm just going to check for
|
||||||
|
* x86 with size 64.
|
||||||
|
*/
|
||||||
|
if (!"x86".equals(proc.toString())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (lang.getLanguageDescription().getSize() != 64) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin.checkDisassemblyEnabled(context, address, true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:ADCX Reg64, rm64 is vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xF6; Reg64 ... & rm64 {
|
:ADCX Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0xF6; Reg64 ... & rm64 {
|
||||||
tmp:9 = zext(Reg64) + zext(rm64) + zext(CF);
|
tmp:9 = zext(Reg64) + zext(rm64) + zext(CF);
|
||||||
tmpCF:1 = tmp(8); # just the carry byte
|
tmpCF:1 = tmp(8); # just the carry byte
|
||||||
CF = tmpCF != 0;
|
CF = tmpCF != 0;
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:ADOX Reg64, rm64 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x38; byte=0xF6; Reg64 ... & rm64 {
|
:ADOX Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x38; byte=0xF6; Reg64 ... & rm64 {
|
||||||
tmp:9 = zext(Reg64) + zext(rm64) + zext(OF);
|
tmp:9 = zext(Reg64) + zext(rm64) + zext(OF);
|
||||||
tmpOF:1 = tmp(8); # just the carry byte
|
tmpOF:1 = tmp(8); # just the carry byte
|
||||||
OF = tmpOF != 0;
|
OF = tmpOF != 0;
|
||||||
|
|
|
@ -684,7 +684,7 @@ define pcodeop vcvtsd2si_avx ;
|
||||||
|
|
||||||
# CVTSD2SI 3-253 PAGE 823 LINE 44317
|
# CVTSD2SI 3-253 PAGE 823 LINE 44317
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VCVTSD2SI Reg64, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1); byte=0x2D; Reg64 ... & XmmReg2_m64
|
:VCVTSD2SI Reg64, XmmReg2_m64 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1); byte=0x2D; Reg64 ... & XmmReg2_m64
|
||||||
{
|
{
|
||||||
Reg64 = vcvtsd2si_avx( XmmReg2_m64 );
|
Reg64 = vcvtsd2si_avx( XmmReg2_m64 );
|
||||||
}
|
}
|
||||||
|
@ -710,7 +710,7 @@ define pcodeop vcvtsi2sd_avx ;
|
||||||
|
|
||||||
# CVTSI2SD 3-257 PAGE 827 LINE 44519
|
# CVTSI2SD 3-257 PAGE 827 LINE 44519
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VCVTSI2SD XmmReg1, vexVVVV_XmmReg, rm64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & YmmReg1) ... & rm64
|
:VCVTSI2SD XmmReg1, vexVVVV_XmmReg, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & YmmReg1) ... & rm64
|
||||||
{
|
{
|
||||||
local tmp:16 = vcvtsi2sd_avx( vexVVVV_XmmReg, rm64 );
|
local tmp:16 = vcvtsi2sd_avx( vexVVVV_XmmReg, rm64 );
|
||||||
YmmReg1 = zext(tmp);
|
YmmReg1 = zext(tmp);
|
||||||
|
@ -729,7 +729,7 @@ define pcodeop vcvtsi2ss_avx ;
|
||||||
|
|
||||||
# CVTSI2SS 3-259 PAGE 829 LINE 44634
|
# CVTSI2SS 3-259 PAGE 829 LINE 44634
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VCVTSI2SS XmmReg1, vexVVVV_XmmReg, rm64 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & YmmReg1) ... & rm64
|
:VCVTSI2SS XmmReg1, vexVVVV_XmmReg, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x2A; (XmmReg1 & YmmReg1) ... & rm64
|
||||||
{
|
{
|
||||||
local tmp:16 = vcvtsi2ss_avx( vexVVVV_XmmReg, rm64 );
|
local tmp:16 = vcvtsi2ss_avx( vexVVVV_XmmReg, rm64 );
|
||||||
YmmReg1 = zext(tmp);
|
YmmReg1 = zext(tmp);
|
||||||
|
@ -756,7 +756,7 @@ define pcodeop vcvtss2si_avx ;
|
||||||
|
|
||||||
# CVTSS2SI 3-263 PAGE 833 LINE 44837
|
# CVTSS2SI 3-263 PAGE 833 LINE 44837
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VCVTSS2SI Reg64, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1); byte=0x2D; Reg64 ... & XmmReg2_m32
|
:VCVTSS2SI Reg64, XmmReg2_m32 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1); byte=0x2D; Reg64 ... & XmmReg2_m32
|
||||||
{
|
{
|
||||||
Reg64 = vcvtss2si_avx( XmmReg2_m32 );
|
Reg64 = vcvtss2si_avx( XmmReg2_m32 );
|
||||||
}
|
}
|
||||||
|
@ -805,7 +805,7 @@ define pcodeop vcvttsd2si_avx ;
|
||||||
|
|
||||||
# CVTTSD2SI 3-274 PAGE 844 LINE 45382
|
# CVTTSD2SI 3-274 PAGE 844 LINE 45382
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VCVTTSD2SI Reg64, XmmReg2_m64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1); byte=0x2C; Reg64 ... & XmmReg2_m64
|
:VCVTTSD2SI Reg64, XmmReg2_m64 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F2) & $(VEX_0F) & $(VEX_W1); byte=0x2C; Reg64 ... & XmmReg2_m64
|
||||||
{
|
{
|
||||||
Reg64 = vcvttsd2si_avx( XmmReg2_m64 );
|
Reg64 = vcvttsd2si_avx( XmmReg2_m64 );
|
||||||
}
|
}
|
||||||
|
@ -821,7 +821,7 @@ define pcodeop vcvttss2si_avx ;
|
||||||
|
|
||||||
# CVTTSS2SI 3-276 PAGE 846 LINE 45476
|
# CVTTSS2SI 3-276 PAGE 846 LINE 45476
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VCVTTSS2SI Reg64, XmmReg2_m32 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1); byte=0x2C; Reg64 ... & XmmReg2_m32
|
:VCVTTSS2SI Reg64, XmmReg2_m32 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_F3) & $(VEX_0F) & $(VEX_W1); byte=0x2C; Reg64 ... & XmmReg2_m32
|
||||||
{
|
{
|
||||||
Reg64 = vcvttss2si_avx( XmmReg2_m32 );
|
Reg64 = vcvttss2si_avx( XmmReg2_m32 );
|
||||||
}
|
}
|
||||||
|
@ -1186,7 +1186,7 @@ define pcodeop vmovd_avx ;
|
||||||
# MOVD/MOVQ 4-55 PAGE 1175 LINE 61360
|
# MOVD/MOVQ 4-55 PAGE 1175 LINE 61360
|
||||||
define pcodeop vmovq_avx ;
|
define pcodeop vmovq_avx ;
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VMOVQ XmmReg1, rm64 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W1); byte=0x6E; (XmmReg1 & YmmReg1) ... & rm64
|
:VMOVQ XmmReg1, rm64 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W1); byte=0x6E; (XmmReg1 & YmmReg1) ... & rm64
|
||||||
{
|
{
|
||||||
local tmp:16 = vmovq_avx( rm64 );
|
local tmp:16 = vmovq_avx( rm64 );
|
||||||
YmmReg1 = zext(tmp);
|
YmmReg1 = zext(tmp);
|
||||||
|
@ -1202,7 +1202,7 @@ define pcodeop vmovq_avx ;
|
||||||
|
|
||||||
# MOVD/MOVQ 4-55 PAGE 1175 LINE 61364
|
# MOVD/MOVQ 4-55 PAGE 1175 LINE 61364
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VMOVQ rm64, XmmReg1 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W1); byte=0x7E; XmmReg1 ... & rm64
|
:VMOVQ rm64, XmmReg1 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F) & $(VEX_W1); byte=0x7E; XmmReg1 ... & rm64
|
||||||
{
|
{
|
||||||
rm64 = vmovq_avx( XmmReg1 );
|
rm64 = vmovq_avx( XmmReg1 );
|
||||||
}
|
}
|
||||||
|
@ -1947,7 +1947,7 @@ define pcodeop vpextrd_avx ;
|
||||||
# PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72330
|
# PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72330
|
||||||
define pcodeop vpextrq_avx ;
|
define pcodeop vpextrq_avx ;
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VPEXTRQ rm64, XmmReg1, imm8 is $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1); byte=0x16; XmmReg1 ... & rm64; imm8
|
:VPEXTRQ rm64, XmmReg1, imm8 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1); byte=0x16; XmmReg1 ... & rm64; imm8
|
||||||
{
|
{
|
||||||
rm64 = vpextrq_avx( XmmReg1, imm8:1 );
|
rm64 = vpextrq_avx( XmmReg1, imm8:1 );
|
||||||
}
|
}
|
||||||
|
@ -2052,7 +2052,7 @@ define pcodeop vpinsrd_avx ;
|
||||||
# PINSRB/PINSRD/PINSRQ 4-293 PAGE 1413 LINE 73327
|
# PINSRB/PINSRD/PINSRQ 4-293 PAGE 1413 LINE 73327
|
||||||
define pcodeop vpinsrq_avx ;
|
define pcodeop vpinsrq_avx ;
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VPINSRQ XmmReg1, vexVVVV_XmmReg, rm64, imm8 is $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x22; (XmmReg1 & YmmReg1) ... & rm64; imm8
|
:VPINSRQ XmmReg1, vexVVVV_XmmReg, rm64, imm8 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F3A) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x22; (XmmReg1 & YmmReg1) ... & rm64; imm8
|
||||||
{
|
{
|
||||||
local tmp:16 = vpinsrq_avx( vexVVVV_XmmReg, rm64, imm8:1 );
|
local tmp:16 = vpinsrq_avx( vexVVVV_XmmReg, rm64, imm8:1 );
|
||||||
YmmReg1 = zext(tmp);
|
YmmReg1 = zext(tmp);
|
||||||
|
|
|
@ -33,7 +33,7 @@ define pcodeop vgatherdpd ;
|
||||||
# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106908
|
# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106908
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
define pcodeop vgatherqpd ;
|
define pcodeop vgatherqpd ;
|
||||||
:VGATHERQPD XmmReg1, q_vm64x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & q_vm64x {
|
:VGATHERQPD XmmReg1, q_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & q_vm64x {
|
||||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||||
# XmmReg1 = vgatherqpd(XmmReg1, q_vm64x, vexVVVV_XmmReg);
|
# XmmReg1 = vgatherqpd(XmmReg1, q_vm64x, vexVVVV_XmmReg);
|
||||||
local tmp:16 = vgatherqpd(XmmReg1, vexVVVV_XmmReg);
|
local tmp:16 = vgatherqpd(XmmReg1, vexVVVV_XmmReg);
|
||||||
|
@ -54,7 +54,7 @@ define pcodeop vgatherqpd ;
|
||||||
|
|
||||||
# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106918
|
# VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106918
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VGATHERQPD YmmReg1, q_vm64y, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x93; YmmReg1 ... & q_vm64y {
|
:VGATHERQPD YmmReg1, q_vm64y, vexVVVV_YmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x93; YmmReg1 ... & q_vm64y {
|
||||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||||
# YmmReg1 = vgatherqpd(YmmReg1, q_vm64y, vexVVVV_YmmReg);
|
# YmmReg1 = vgatherqpd(YmmReg1, q_vm64y, vexVVVV_YmmReg);
|
||||||
YmmReg1 = vgatherqpd(YmmReg1, vexVVVV_YmmReg);
|
YmmReg1 = vgatherqpd(YmmReg1, vexVVVV_YmmReg);
|
||||||
|
@ -78,7 +78,7 @@ define pcodeop vgatherdps ;
|
||||||
# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107135
|
# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107135
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
define pcodeop vgatherqps ;
|
define pcodeop vgatherqps ;
|
||||||
:VGATHERQPS XmmReg1, d_vm64x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & d_vm64x {
|
:VGATHERQPS XmmReg1, d_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & d_vm64x {
|
||||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||||
# XmmReg1 = vgatherqps(XmmReg1, d_vm64x, vexVVVV_XmmReg);
|
# XmmReg1 = vgatherqps(XmmReg1, d_vm64x, vexVVVV_XmmReg);
|
||||||
local tmp:16 = vgatherqps(XmmReg1, vexVVVV_XmmReg);
|
local tmp:16 = vgatherqps(XmmReg1, vexVVVV_XmmReg);
|
||||||
|
@ -99,7 +99,7 @@ define pcodeop vgatherqps ;
|
||||||
|
|
||||||
# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107145
|
# VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107145
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VGATHERQPS XmmReg1, d_vm64y, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & d_vm64y {
|
:VGATHERQPS XmmReg1, d_vm64y, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x93; (XmmReg1 & YmmReg1) ... & d_vm64y {
|
||||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||||
# XmmReg1 = vgatherqps(XmmReg1, d_vm64y, vexVVVV_XmmReg);
|
# XmmReg1 = vgatherqps(XmmReg1, d_vm64y, vexVVVV_XmmReg);
|
||||||
XmmReg1 = vgatherqps(XmmReg1, vexVVVV_XmmReg);
|
XmmReg1 = vgatherqps(XmmReg1, vexVVVV_XmmReg);
|
||||||
|
@ -133,7 +133,7 @@ define pcodeop vpgatherdd ;
|
||||||
# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107888
|
# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107888
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
define pcodeop vpgatherqd ;
|
define pcodeop vpgatherqd ;
|
||||||
:VPGATHERQD XmmReg1, d_vm64x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & d_vm64x {
|
:VPGATHERQD XmmReg1, d_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & d_vm64x {
|
||||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||||
# XmmReg1 = vpgatherqd(XmmReg1, d_vm64x, vexVVVV_XmmReg);
|
# XmmReg1 = vpgatherqd(XmmReg1, d_vm64x, vexVVVV_XmmReg);
|
||||||
local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg);
|
local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg);
|
||||||
|
@ -154,7 +154,7 @@ define pcodeop vpgatherqd ;
|
||||||
|
|
||||||
# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107896
|
# VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107896
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VPGATHERQD XmmReg1, d_vm64y, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & d_vm64y {
|
:VPGATHERQD XmmReg1, d_vm64y, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W0) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & d_vm64y {
|
||||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||||
# XmmReg1 = vpgatherqd(XmmReg1, d_vm64y, vexVVVV_XmmReg);
|
# XmmReg1 = vpgatherqd(XmmReg1, d_vm64y, vexVVVV_XmmReg);
|
||||||
local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg);
|
local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg);
|
||||||
|
@ -179,7 +179,7 @@ define pcodeop vpgatherdq ;
|
||||||
# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108238
|
# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108238
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
define pcodeop vpgatherqq ;
|
define pcodeop vpgatherqq ;
|
||||||
:VPGATHERQQ XmmReg1, q_vm64x, vexVVVV_XmmReg is $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & q_vm64x {
|
:VPGATHERQQ XmmReg1, q_vm64x, vexVVVV_XmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L128) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_XmmReg; byte=0x91; (XmmReg1 & YmmReg1) ... & q_vm64x {
|
||||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||||
# XmmReg1 = vpgatherqq(XmmReg1, q_vm64x, vexVVVV_XmmReg);
|
# XmmReg1 = vpgatherqq(XmmReg1, q_vm64x, vexVVVV_XmmReg);
|
||||||
local tmp:16 = vpgatherqq(XmmReg1, vexVVVV_XmmReg);
|
local tmp:16 = vpgatherqq(XmmReg1, vexVVVV_XmmReg);
|
||||||
|
@ -200,7 +200,7 @@ define pcodeop vpgatherqq ;
|
||||||
|
|
||||||
# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108246
|
# VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108246
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:VPGATHERQQ YmmReg1, q_vm64y, vexVVVV_YmmReg is $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x91; YmmReg1 ... & q_vm64y {
|
:VPGATHERQQ YmmReg1, q_vm64y, vexVVVV_YmmReg is $(LONGMODE_ON) & $(VEX_DDS) & $(VEX_L256) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_YmmReg; byte=0x91; YmmReg1 ... & q_vm64y {
|
||||||
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
# TODO full semantics necessary for VSIB memory data access, leave out of data flow for now
|
||||||
# YmmReg1 = vpgatherqq(YmmReg1, q_vm64y, vexVVVV_YmmReg);
|
# YmmReg1 = vpgatherqq(YmmReg1, q_vm64y, vexVVVV_YmmReg);
|
||||||
YmmReg1 = vpgatherqq(YmmReg1, vexVVVV_YmmReg);
|
YmmReg1 = vpgatherqq(YmmReg1, vexVVVV_YmmReg);
|
||||||
|
|
|
@ -21,7 +21,7 @@ macro tzcntflags(input, output) {
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
# TODO remove ANDN from ia.sinc ?????
|
# TODO remove ANDN from ia.sinc ?????
|
||||||
:ANDN Reg64, vexVVVV_r64, rm64 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf2; Reg64 ... & rm64
|
:ANDN Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf2; Reg64 ... & rm64
|
||||||
{
|
{
|
||||||
Reg64 = ~(vexVVVV_r64) & rm64;
|
Reg64 = ~(vexVVVV_r64) & rm64;
|
||||||
resultflags(Reg64);
|
resultflags(Reg64);
|
||||||
|
@ -46,7 +46,7 @@ macro tzcntflags(input, output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:BEXTR Reg64, rm64, vexVVVV_r64 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
:BEXTR Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
||||||
{
|
{
|
||||||
sourceTmp:1 = vexVVVV_r64[0,8];
|
sourceTmp:1 = vexVVVV_r64[0,8];
|
||||||
lengthTmp:1 = vexVVVV_r64[8,8];
|
lengthTmp:1 = vexVVVV_r64[8,8];
|
||||||
|
@ -74,7 +74,7 @@ macro tzcntflags(input, output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:BLSI vexVVVV_r64, rm64 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=3 ... & rm64
|
:BLSI vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=3 ... & rm64
|
||||||
{
|
{
|
||||||
vexVVVV_r64 = -rm64 & rm64;
|
vexVVVV_r64 = -rm64 & rm64;
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ macro tzcntflags(input, output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:BLSMSK vexVVVV_r64, rm64 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=2 ... & rm64
|
:BLSMSK vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=2 ... & rm64
|
||||||
{
|
{
|
||||||
CF = (rm64 == 0);
|
CF = (rm64 == 0);
|
||||||
vexVVVV_r64 = (rm64 - 1) ^ rm64;
|
vexVVVV_r64 = (rm64 - 1) ^ rm64;
|
||||||
|
@ -126,7 +126,7 @@ macro tzcntflags(input, output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:BLSR vexVVVV_r64, rm64 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=1 ... & rm64
|
:BLSR vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf3; reg_opcode=1 ... & rm64
|
||||||
{
|
{
|
||||||
CF = (rm64 == 0);
|
CF = (rm64 == 0);
|
||||||
vexVVVV_r64 = (rm64 - 1) & rm64;
|
vexVVVV_r64 = (rm64 - 1) & rm64;
|
||||||
|
@ -176,7 +176,7 @@ macro tzcntflags(input, output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:TZCNT Reg64, rm64 is vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBC; Reg64 ... & rm64 {
|
:TZCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBC; Reg64 ... & rm64 {
|
||||||
|
|
||||||
countTmp:8 = 0;
|
countTmp:8 = 0;
|
||||||
inputTmp:8 = rm64;
|
inputTmp:8 = rm64;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:BZHI Reg64, rm64, vexVVVV_r64 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64
|
:BZHI Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_NONE) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64
|
||||||
{
|
{
|
||||||
indexTmp:1 = vexVVVV_r64:1;
|
indexTmp:1 = vexVVVV_r64:1;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:MULX Reg64, vexVVVV_r64, rm64 is $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf6; Reg64 ... & rm64
|
:MULX Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDD) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf6; Reg64 ... & rm64
|
||||||
{
|
{
|
||||||
temp:16 = zext(RDX) * zext(rm64);
|
temp:16 = zext(RDX) * zext(rm64);
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:PDEP Reg64, vexVVVV_r64, rm64 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64
|
:PDEP Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64
|
||||||
{
|
{
|
||||||
sourceTmp:8 = vexVVVV_r64;
|
sourceTmp:8 = vexVVVV_r64;
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:PEXT Reg64, vexVVVV_r64, rm64 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64
|
:PEXT Reg64, vexVVVV_r64, rm64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf5; Reg64 ... & rm64
|
||||||
{
|
{
|
||||||
indexTmp:8 = 0x8000000000000000;
|
indexTmp:8 = 0x8000000000000000;
|
||||||
resultTmp:8 = 0;
|
resultTmp:8 = 0;
|
||||||
|
@ -157,7 +157,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:RORX Reg64, rm64, imm8 is $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F3A) & $(VEX_W1); byte=0xf0; Reg64 ... & rm64; imm8
|
:RORX Reg64, rm64, imm8 is $(LONGMODE_ON) & $(VEX_NONE) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F3A) & $(VEX_W1); byte=0xf0; Reg64 ... & rm64; imm8
|
||||||
{
|
{
|
||||||
shiftTmp:1 = (imm8:1 & 0x3F);
|
shiftTmp:1 = (imm8:1 & 0x3F);
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:SARX Reg64, rm64, vexVVVV_r64 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
:SARX Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F3) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
||||||
{
|
{
|
||||||
Reg64 = rm64 s>> (vexVVVV_r64 & 0x000000000000003F);
|
Reg64 = rm64 s>> (vexVVVV_r64 & 0x000000000000003F);
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:SHLX Reg64, rm64, vexVVVV_r64 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
:SHLX Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_66) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
||||||
{
|
{
|
||||||
Reg64 = rm64 << (vexVVVV_r64 & 0x000000000000003F);
|
Reg64 = rm64 << (vexVVVV_r64 & 0x000000000000003F);
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:SHRX Reg64, rm64, vexVVVV_r64 is $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
:SHRX Reg64, rm64, vexVVVV_r64 is $(LONGMODE_ON) & $(VEX_NDS) & $(VEX_LZ) & $(VEX_PRE_F2) & $(VEX_0F38) & $(VEX_W1) & vexVVVV_r64; byte=0xf7; Reg64 ... & rm64
|
||||||
{
|
{
|
||||||
Reg64 = rm64 >> (vexVVVV_r64 & 0x000000000000003F);
|
Reg64 = rm64 >> (vexVVVV_r64 & 0x000000000000003F);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ define pcodeop ShadowStackLoad4B;
|
||||||
SSP = SSP + zext(4 * r32:1);
|
SSP = SSP + zext(4 * r32:1);
|
||||||
}
|
}
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:INCSSPQ r64 is vexMode=0 & $(PRE_F3) & $(REX_W) & byte=0x0f; byte=0xae; reg_opcode=5 & r64 {
|
:INCSSPQ r64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & $(REX_W) & byte=0x0f; byte=0xae; reg_opcode=5 & r64 {
|
||||||
SSP = SSP + zext(8 * r64:1);
|
SSP = SSP + zext(8 * r64:1);
|
||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
|
@ -25,7 +25,7 @@ define pcodeop ShadowStackLoad4B;
|
||||||
r32 = SSP:4;
|
r32 = SSP:4;
|
||||||
}
|
}
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:RDSSPQ r64 is vexMode=0 & $(PRE_F3) & $(REX_W) & byte=0x0f; byte=0x1e; mod=3 & reg_opcode=1 & r64 {
|
:RDSSPQ r64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & $(REX_W) & byte=0x0f; byte=0x1e; mod=3 & reg_opcode=1 & r64 {
|
||||||
r64 = SSP;
|
r64 = SSP;
|
||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
|
@ -50,7 +50,7 @@ define pcodeop writeToUserShadowStack;
|
||||||
writeToShadowStack(rm32, Reg32);
|
writeToShadowStack(rm32, Reg32);
|
||||||
}
|
}
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:WRSSQ rm64,Reg64 is vexMode=0 & $(REX_W) & byte=0x0f; byte=0x0f; byte=0x38; byte=0xf6; rm64 & Reg64 ... {
|
:WRSSQ rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0f; byte=0x0f; byte=0x38; byte=0xf6; rm64 & Reg64 ... {
|
||||||
writeToShadowStack(rm64, Reg64);
|
writeToShadowStack(rm64, Reg64);
|
||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
|
@ -59,7 +59,7 @@ define pcodeop writeToUserShadowStack;
|
||||||
writeToUserShadowStack(rm32, Reg32);
|
writeToUserShadowStack(rm32, Reg32);
|
||||||
}
|
}
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:WRUSSQ rm64,Reg64 is vexMode=0 & $(PRE_66) & $(REX_W) & byte=0x0f; byte=0x0f; byte=0x38; byte=0xf5; rm64 & Reg64 ... {
|
:WRUSSQ rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & $(REX_W) & byte=0x0f; byte=0x0f; byte=0x38; byte=0xf5; rm64 & Reg64 ... {
|
||||||
writeToUserShadowStack(rm64, Reg64);
|
writeToUserShadowStack(rm64, Reg64);
|
||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
|
@ -78,7 +78,7 @@ define pcodeop clearShadowStackBusy;
|
||||||
|
|
||||||
:ENDBR32 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; byte=0xfb {}
|
:ENDBR32 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; byte=0xfb {}
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:ENDBR64 is vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; byte=0xfa {}
|
:ENDBR64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & (opsize=0 | opsize=1 | opsize=2 | opsize=3) & byte=0x0f; byte=0x1e; byte=0xfa {}
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ define pcodeop clwb;
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
define pcodeop clflushopt;
|
define pcodeop clflushopt;
|
||||||
:CLFLUSHOPT m8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xAE; m8 & reg_opcode=7 ... {
|
:CLFLUSHOPT m8 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0xAE; m8 & reg_opcode=7 ... {
|
||||||
clflushopt(m8);
|
clflushopt(m8);
|
||||||
}
|
}
|
||||||
@endif
|
@endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -46,7 +46,7 @@ macro lzcntflags(input, output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:LZCNT Reg64, rm64 is vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBD; Reg64 ... & rm64 {
|
:LZCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xBD; Reg64 ... & rm64 {
|
||||||
|
|
||||||
countTmp:8 = 0;
|
countTmp:8 = 0;
|
||||||
inputTmp:8 = rm64;
|
inputTmp:8 = rm64;
|
||||||
|
|
|
@ -5,7 +5,6 @@ define pcodeop br_exception;
|
||||||
# - if no base register, needs 0
|
# - if no base register, needs 0
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
|
|
||||||
bndmk_addr64: [Rmr64] is mod=0 & Rmr64 { export Rmr64; }
|
bndmk_addr64: [Rmr64] is mod=0 & Rmr64 { export Rmr64; }
|
||||||
bndmk_addr64: [Rmr64 + simm8_64] is mod=1 & Rmr64; simm8_64 { export Rmr64; }
|
bndmk_addr64: [Rmr64 + simm8_64] is mod=1 & Rmr64; simm8_64 { export Rmr64; }
|
||||||
bndmk_addr64: [simm32_64 + Rmr64] is mod=2 & Rmr64; simm32_64 { export Rmr64; }
|
bndmk_addr64: [simm32_64 + Rmr64] is mod=2 & Rmr64; simm32_64 { export Rmr64; }
|
||||||
|
@ -24,8 +23,8 @@ bndmk_addr64: [simm32_64 + Base64 + Index64*ss] is mod=2 & r_m=4; Index64 & Base
|
||||||
bndmk_addr64: [simm32_64 + Base64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; simm32_64 { export Base64; }
|
bndmk_addr64: [simm32_64 + Base64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; simm32_64 { export Base64; }
|
||||||
bndmk_addr64: [Base64 + Index64*ss] is mod=2 & r_m=4; Index64 & Base64 & ss; imm32=0 { export Base64; }
|
bndmk_addr64: [Base64 + Index64*ss] is mod=2 & r_m=4; Index64 & Base64 & ss; imm32=0 { export Base64; }
|
||||||
bndmk_addr64: [Base64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; imm32=0 { export Base64; }
|
bndmk_addr64: [Base64] is mod=2 & r_m=4; rexXprefix=0 & index64=4 & Base64; imm32=0 { export Base64; }
|
||||||
|
@endif
|
||||||
|
|
||||||
@else
|
|
||||||
bndmk_addr32: [Rmr32] is mod=0 & Rmr32 { export Rmr32; }
|
bndmk_addr32: [Rmr32] is mod=0 & Rmr32 { export Rmr32; }
|
||||||
bndmk_addr32: [Rmr32 + simm8_32] is mod=1 & Rmr32; simm8_32 { export Rmr32; }
|
bndmk_addr32: [Rmr32 + simm8_32] is mod=1 & Rmr32; simm8_32 { export Rmr32; }
|
||||||
bndmk_addr32: [Rmr32] is mod=1 & r_m!=4 & Rmr32; simm8=0 { export Rmr32; }
|
bndmk_addr32: [Rmr32] is mod=1 & r_m!=4 & Rmr32; simm8=0 { export Rmr32; }
|
||||||
|
@ -44,13 +43,12 @@ bndmk_addr32: [imm32 + Base + Index*ss] is mod=2 & r_m=4; Index & Base & ss; i
|
||||||
bndmk_addr32: [imm32 + Base] is mod=2 & r_m=4; index=4 & Base; imm32 { export Base; }
|
bndmk_addr32: [imm32 + Base] is mod=2 & r_m=4; index=4 & Base; imm32 { export Base; }
|
||||||
bndmk_addr32: [Base + Index*ss] is mod=2 & r_m=4; Index & Base & ss; imm32=0 { export Base; }
|
bndmk_addr32: [Base + Index*ss] is mod=2 & r_m=4; Index & Base & ss; imm32=0 { export Base; }
|
||||||
bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export Base; }
|
bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export Base; }
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
|
|
||||||
:BNDCL bnd1, Rmr64 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_lb & Rmr64 {
|
:BNDCL bnd1, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_lb & Rmr64 {
|
||||||
# if (reg < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (reg < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(Rmr64 < bnd1_lb) goto <done>;
|
if !(Rmr64 < bnd1_lb) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -58,7 +56,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCL bnd1, Mem is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_lb) ... & Mem {
|
:BNDCL bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_lb) ... & Mem {
|
||||||
# if (LEA(mem) < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (LEA(mem) < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(Mem < bnd1_lb) goto <done>;
|
if !(Mem < bnd1_lb) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -66,7 +64,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCU bnd1, Rmr64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_ub & Rmr64 {
|
:BNDCU bnd1, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_ub & Rmr64 {
|
||||||
# if (reg > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (reg > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(Rmr64 > ~bnd1_ub) goto <done>;
|
if !(Rmr64 > ~bnd1_ub) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -74,7 +72,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCU bnd1, Mem is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_ub) ... & Mem {
|
:BNDCU bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_ub) ... & Mem {
|
||||||
# if (LEA(mem) > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (LEA(mem) > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(Mem > ~bnd1_ub) goto <done>;
|
if !(Mem > ~bnd1_ub) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -82,7 +80,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCN bnd1, Rmr64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd1_ub & Rmr64 {
|
:BNDCN bnd1, Rmr64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd1_ub & Rmr64 {
|
||||||
# if (reg > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (reg > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(Rmr64 > bnd1_ub) goto <done>;
|
if !(Rmr64 > bnd1_ub) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -90,7 +88,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCN bnd1, Mem is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; (bnd1 & bnd1_ub) ... & Mem {
|
:BNDCN bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; (bnd1 & bnd1_ub) ... & Mem {
|
||||||
# if (LEA(mem) > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (LEA(mem) > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(Mem > bnd1_ub) goto <done>;
|
if !(Mem > bnd1_ub) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -99,7 +97,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
}
|
}
|
||||||
|
|
||||||
#TODO: This probably cannot be fully modeled
|
#TODO: This probably cannot be fully modeled
|
||||||
:BNDLDX bnd1, Mem is vexMode=0 & byte=0x0F; byte=0x1A; bnd1 ... & Mem {
|
:BNDLDX bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & byte=0x0F; byte=0x1A; bnd1 ... & Mem {
|
||||||
# BNDSTATUS = bndldx_status( Mem, BNDCFGS, BNDCFGU );
|
# BNDSTATUS = bndldx_status( Mem, BNDCFGS, BNDCFGU );
|
||||||
# bnd1 = bndldx( Mem, BNDCFGS, BNDCFGU );
|
# bnd1 = bndldx( Mem, BNDCFGS, BNDCFGU );
|
||||||
|
|
||||||
|
@ -107,30 +105,30 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
bnd1 = *:16 Mem;
|
bnd1 = *:16 Mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMK bnd1, Mem is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & ( bndmk_addr64 & Mem ) {
|
:BNDMK bnd1, Mem is $(LONGMODE_ON) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & ( bndmk_addr64 & Mem ) {
|
||||||
# BND.LB and BND.UB set from m64
|
# BND.LB and BND.UB set from m64
|
||||||
bnd1_lb = bndmk_addr64;
|
bnd1_lb = bndmk_addr64;
|
||||||
bnd1_ub = Mem;
|
bnd1_ub = Mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMOV bnd1, m128 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; bnd1 ... & m128 {
|
:BNDMOV bnd1, m128 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; bnd1 ... & m128 {
|
||||||
bnd1 = m128;
|
bnd1 = m128;
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMOV bnd1, bnd2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd2 {
|
:BNDMOV bnd1, bnd2 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd2 {
|
||||||
bnd1 = bnd2;
|
bnd1 = bnd2;
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMOV m128, bnd1 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; bnd1 ... & m128 {
|
:BNDMOV m128, bnd1 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; bnd1 ... & m128 {
|
||||||
m128 = bnd1;
|
m128 = bnd1;
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMOV bnd2, bnd1 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd2 {
|
:BNDMOV bnd2, bnd1 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd2 {
|
||||||
bnd2 = bnd1;
|
bnd2 = bnd1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#TODO: This probably cannot be fully modeled
|
#TODO: This probably cannot be fully modeled
|
||||||
:BNDSTX Mem, bnd1 is vexMode=0 & byte=0x0F; byte=0x1B; bnd1 ... & Mem {
|
:BNDSTX Mem, bnd1 is $(LONGMODE_ON) & vexMode=0 & byte=0x0F; byte=0x1B; bnd1 ... & Mem {
|
||||||
# BNDSTATUS = bndstx_status( bnd1, BNDCFGS, BNDCFGU );
|
# BNDSTATUS = bndstx_status( bnd1, BNDCFGS, BNDCFGU );
|
||||||
# Mem = bndstx( bnd1, BNDCFGS, BNDCFGU );
|
# Mem = bndstx( bnd1, BNDCFGS, BNDCFGU );
|
||||||
|
|
||||||
|
@ -138,11 +136,9 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
*:16 Mem = bnd1;
|
*:16 Mem = bnd1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
|
:BNDCL bnd1, Rmr32 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_lb & Rmr32 {
|
||||||
@else
|
|
||||||
|
|
||||||
:BNDCL bnd1, Rmr32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_lb & Rmr32 {
|
|
||||||
# if (reg < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (reg < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(zext(Rmr32) < bnd1_lb) goto <done>;
|
if !(zext(Rmr32) < bnd1_lb) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -150,7 +146,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCL bnd1, Mem is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_lb) ... & Mem {
|
:BNDCL bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_lb) ... & Mem {
|
||||||
# if (LEA(mem) < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (LEA(mem) < BND.LB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(zext(Mem) < bnd1_lb) goto <done>;
|
if !(zext(Mem) < bnd1_lb) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -158,7 +154,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCU bnd1, Rmr32 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_ub & Rmr32 {
|
:BNDCU bnd1, Rmr32 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_ub & Rmr32 {
|
||||||
# if (reg > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (reg > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(zext(Rmr32) > ~bnd1_ub) goto <done>;
|
if !(zext(Rmr32) > ~bnd1_ub) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -166,7 +162,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCU bnd1, Mem is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_ub) ... & Mem {
|
:BNDCU bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1A; (bnd1 & bnd1_ub) ... & Mem {
|
||||||
# if (LEA(mem) > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (LEA(mem) > ~(BND.UB)) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(zext(Mem) > ~bnd1_ub) goto <done>;
|
if !(zext(Mem) > ~bnd1_ub) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -174,7 +170,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCN bnd1, Rmr32 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd1_ub & Rmr32 {
|
:BNDCN bnd1, Rmr32 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd1_ub & Rmr32 {
|
||||||
# if (reg > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (reg > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(zext(Rmr32) > bnd1_ub) goto <done>;
|
if !(zext(Rmr32) > bnd1_ub) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -182,7 +178,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
<done>
|
<done>
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDCN bnd1, Mem is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; (bnd1 & bnd1_ub) ... & Mem {
|
:BNDCN bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x1B; (bnd1 & bnd1_ub) ... & Mem {
|
||||||
# if (LEA(mem) > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
# if (LEA(mem) > BND.UB) then BNDSTATUS = 01H; AND BOUND EXCEPTION
|
||||||
if !(zext(Mem) > bnd1_ub) goto <done>;
|
if !(zext(Mem) > bnd1_ub) goto <done>;
|
||||||
BNDSTATUS = 0x01;
|
BNDSTATUS = 0x01;
|
||||||
|
@ -191,7 +187,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
}
|
}
|
||||||
|
|
||||||
#TODO: This probably cannot be fully modeled
|
#TODO: This probably cannot be fully modeled
|
||||||
:BNDLDX bnd1, Mem is vexMode=0 & byte=0x0F; byte=0x1A; ( bnd1 & bnd1_lb & bnd1_ub ) ... & Mem {
|
:BNDLDX bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & byte=0x0F; byte=0x1A; ( bnd1 & bnd1_lb & bnd1_ub ) ... & Mem {
|
||||||
# BNDSTATUS = bndldx_status( Mem, BNDCFGS, BNDCFGU );
|
# BNDSTATUS = bndldx_status( Mem, BNDCFGS, BNDCFGU );
|
||||||
# bnd1 = bndldx( Mem, BNDCFGS, BNDCFGU );
|
# bnd1 = bndldx( Mem, BNDCFGS, BNDCFGU );
|
||||||
|
|
||||||
|
@ -202,33 +198,33 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
bnd1_ub = zext(tmp2);
|
bnd1_ub = zext(tmp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMK bnd1, Mem is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & ( bndmk_addr32 & Mem ) {
|
:BNDMK bnd1, Mem is $(LONGMODE_OFF) & vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & ( bndmk_addr32 & Mem ) {
|
||||||
# BND.LB and BND.UB set from m32
|
# BND.LB and BND.UB set from m32
|
||||||
bnd1_lb = zext(bndmk_addr32);
|
bnd1_lb = zext(bndmk_addr32);
|
||||||
bnd1_ub = zext(Mem);
|
bnd1_ub = zext(Mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMOV bnd1, m64 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; ( bnd1 & bnd1_lb & bnd1_ub ) ... & m64 {
|
:BNDMOV bnd1, m64 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; ( bnd1 & bnd1_lb & bnd1_ub ) ... & m64 {
|
||||||
tmp:8 = m64;
|
tmp:8 = m64;
|
||||||
bnd1_lb = zext(tmp:4);
|
bnd1_lb = zext(tmp:4);
|
||||||
tmp2:4 = tmp(4);
|
tmp2:4 = tmp(4);
|
||||||
bnd1_ub = zext(tmp2);
|
bnd1_ub = zext(tmp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMOV bnd1, bnd2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd2 {
|
:BNDMOV bnd1, bnd2 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd2 {
|
||||||
bnd1 = bnd2;
|
bnd1 = bnd2;
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMOV m64, bnd1 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & m64 {
|
:BNDMOV m64, bnd1 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & m64 {
|
||||||
m64 = (zext(bnd1_ub:4) << 32) | zext(bnd1_lb:4);
|
m64 = (zext(bnd1_ub:4) << 32) | zext(bnd1_lb:4);
|
||||||
}
|
}
|
||||||
|
|
||||||
:BNDMOV bnd2, bnd1 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd2 {
|
:BNDMOV bnd2, bnd1 is $(LONGMODE_OFF) & vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x1B; mod=3 & bnd1 & bnd2 {
|
||||||
bnd2 = bnd1;
|
bnd2 = bnd1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#TODO: This probably cannot be fully modeled
|
#TODO: This probably cannot be fully modeled
|
||||||
:BNDSTX Mem, bnd1 is vexMode=0 & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & Mem {
|
:BNDSTX Mem, bnd1 is $(LONGMODE_OFF) & vexMode=0 & byte=0x0F; byte=0x1B; ( bnd1 & bnd1_lb & bnd1_ub ) ... & Mem {
|
||||||
# BNDSTATUS = bndstx_status( bnd1, BNDCFGS, BNDCFGU );
|
# BNDSTATUS = bndstx_status( bnd1, BNDCFGS, BNDCFGU );
|
||||||
# Mem = bndstx( bnd1, BNDCFGS, BNDCFGU );
|
# Mem = bndstx( bnd1, BNDCFGS, BNDCFGU );
|
||||||
|
|
||||||
|
@ -236,5 +232,3 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B
|
||||||
*:8 Mem = (zext(bnd1_ub:4) << 32) | zext(bnd1_lb:4);
|
*:8 Mem = (zext(bnd1_ub:4) << 32) | zext(bnd1_lb:4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@endif
|
|
||||||
|
|
|
@ -3,5 +3,5 @@ define pcodeop rdrandIsValid;
|
||||||
:RDRAND rm16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; (rm16 & reg_opcode=6 ...) { rm16 = rdrand(); CF=rdrandIsValid(); }
|
:RDRAND rm16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; (rm16 & reg_opcode=6 ...) { rm16 = rdrand(); CF=rdrandIsValid(); }
|
||||||
:RDRAND rm32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; (rm32 & reg_opcode=6 ...) { rm32 = rdrand(); CF=rdrandIsValid(); }
|
:RDRAND rm32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; (rm32 & reg_opcode=6 ...) { rm32 = rdrand(); CF=rdrandIsValid(); }
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:RDRAND rm64 is vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; (rm64 & reg_opcode=6 ...) { rm64 = rdrand(); CF=rdrandIsValid(); }
|
:RDRAND rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; (rm64 & reg_opcode=6 ...) { rm64 = rdrand(); CF=rdrandIsValid(); }
|
||||||
@endif
|
@endif
|
||||||
|
|
|
@ -3,5 +3,5 @@ define pcodeop rdseedIsValid;
|
||||||
:RDSEED r16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; r16 & reg_opcode=7 { r16 = rdseed(); CF=rdseedIsValid(); }
|
:RDSEED r16 is vexMode=0 & opsize=0 & byte=0x0f; byte=0xC7; r16 & reg_opcode=7 { r16 = rdseed(); CF=rdseedIsValid(); }
|
||||||
:RDSEED r32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; r32 & reg_opcode=7 { r32 = rdseed(); CF=rdseedIsValid(); }
|
:RDSEED r32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; r32 & reg_opcode=7 { r32 = rdseed(); CF=rdseedIsValid(); }
|
||||||
@ifdef IA64
|
@ifdef IA64
|
||||||
:RDSEED r64 is vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; r64 & reg_opcode=7 { r64 = rdseed(); CF=rdseedIsValid(); }
|
:RDSEED r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(REX_W) & byte=0x0f; byte=0xC7; r64 & reg_opcode=7 { r64 = rdseed(); CF=rdseedIsValid(); }
|
||||||
@endif
|
@endif
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
<set name="bit64" val="1"/>
|
<set name="bit64" val="1"/>
|
||||||
<set name="opsize" val="1"/>
|
<set name="opsize" val="1"/>
|
||||||
<set name="rexprefix" val="0"/>
|
<set name="rexprefix" val="0"/>
|
||||||
|
<set name="longMode" val="1"/>
|
||||||
</context_set>
|
</context_set>
|
||||||
<tracked_set space="ram">
|
<tracked_set space="ram">
|
||||||
<set name="DF" val="0"/>
|
<set name="DF" val="0"/>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue