Merge remote-tracking branch 'origin/GP-1255_Dan_wow64--SQUASHED'

This commit is contained in:
Ryan Kurtz 2021-10-07 09:21:03 -04:00
commit 03b0decf4f
20 changed files with 840 additions and 509 deletions

View file

@ -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

View file

@ -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.
} }

View file

@ -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());
}
}
} }

View file

@ -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) {
@ -62,22 +62,22 @@ 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);
} }
/** /**
* 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) {
@ -105,11 +106,11 @@ 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";
} }
@ -312,7 +317,7 @@ public class DisassembleCommand extends BackgroundCommand {
* *
* @param disassembler disassembler to use * @param disassembler disassembler to use
* @param seedSet set of addresses to be disassembled * @param seedSet set of addresses to be disassembled
* @param mgr * @param mgr
* *
* @return addresses actually disassembled * @return addresses actually disassembled
*/ */
@ -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() {

View file

@ -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);
}
}

View file

@ -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);
}
} }

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);
} }

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"/>