From 25801da834416d05de616b250afc55bf5ab9674e Mon Sep 17 00:00:00 2001 From: Dan <46821332+nsadeveloper789@users.noreply.github.com> Date: Wed, 25 Aug 2021 16:02:35 -0400 Subject: [PATCH] GP-1255: Allowing 32-bit x86 disassembly in x86-64 (WoW64). --- .../gui/listing/DebuggerListingProvider.java | 5 + .../platform/DbgengX64DisassemblyInject.java | 13 +- .../DBTraceDisassemblerIntegrationTest.java | 73 +- .../cmd/disassemble/DisassembleCommand.java | 75 +- .../disassemble/X86_64DisassembleCommand.java | 158 ++++ .../core/disassembler/DisassemblerPlugin.java | 64 +- .../disassembler/X86_64DisassembleAction.java | 80 ++ Ghidra/Processors/x86/data/languages/adx.sinc | 4 +- Ghidra/Processors/x86/data/languages/avx.sinc | 20 +- .../x86/data/languages/avx2_manual.sinc | 16 +- .../Processors/x86/data/languages/bmi1.sinc | 12 +- .../Processors/x86/data/languages/bmi2.sinc | 16 +- Ghidra/Processors/x86/data/languages/cet.sinc | 10 +- .../Processors/x86/data/languages/clwb.sinc | 2 +- Ghidra/Processors/x86/data/languages/ia.sinc | 732 +++++++++--------- .../Processors/x86/data/languages/lzcnt.sinc | 2 +- Ghidra/Processors/x86/data/languages/mpx.sinc | 62 +- .../Processors/x86/data/languages/rdrand.sinc | 2 +- .../Processors/x86/data/languages/rdseed.sinc | 2 +- .../x86/data/languages/x86-64.pspec | 1 + 20 files changed, 840 insertions(+), 509 deletions(-) create mode 100644 Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/X86_64DisassembleCommand.java create mode 100644 Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/X86_64DisassembleAction.java diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java index 2cd5ec889e..e1d506d6b5 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java @@ -344,6 +344,11 @@ public class DebuggerListingProvider extends CodeViewerProvider { return current.isAliveAndPresent(); } + @Override + public boolean isDynamicListing() { + return true; + } + @Override public String getWindowGroup() { //TODO: Overriding this to align disconnected providers diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/DbgengX64DisassemblyInject.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/DbgengX64DisassemblyInject.java index 30d846fa47..a381379428 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/DbgengX64DisassemblyInject.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/DbgengX64DisassemblyInject.java @@ -71,20 +71,15 @@ public class DbgengX64DisassemblyInject implements DisassemblyInject { } Mode mode = modes.iterator().next(); Language lang = trace.getBaseLanguage(); - Register addrsizeReg = lang.getRegister("addrsize"); - Register opsizeReg = lang.getRegister("opsize"); + Register longModeReg = lang.getRegister("longMode"); ProgramContextImpl context = new ProgramContextImpl(lang); lang.applyContextSettings(context); - RegisterValue ctxVal = context.getDisassemblyContext(first.getMinAddress()); + RegisterValue ctxVal = new RegisterValue(context.getBaseContextRegister()); if (mode == Mode.X64) { - command.setInitialContext(ctxVal - .assign(addrsizeReg, BigInteger.TWO) - .assign(opsizeReg, BigInteger.TWO)); + command.setInitialContext(ctxVal.assign(longModeReg, BigInteger.ONE)); } else if (mode == Mode.X86) { - command.setInitialContext(ctxVal - .assign(addrsizeReg, BigInteger.ONE) - .assign(opsizeReg, BigInteger.ONE)); + command.setInitialContext(ctxVal.assign(longModeReg, BigInteger.ZERO)); } // Shouldn't ever get anything else. } diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/program/DBTraceDisassemblerIntegrationTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/program/DBTraceDisassemblerIntegrationTest.java index f7e5382e7e..bc571eb9f9 100644 --- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/program/DBTraceDisassemblerIntegrationTest.java +++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/database/program/DBTraceDisassemblerIntegrationTest.java @@ -25,8 +25,7 @@ import org.junit.*; import com.google.common.collect.Range; -import ghidra.app.cmd.disassemble.ArmDisassembleCommand; -import ghidra.app.cmd.disassemble.MipsDisassembleCommand; +import ghidra.app.cmd.disassemble.*; import ghidra.program.database.ProgramBuilder; import ghidra.program.disassemble.Disassembler; import ghidra.program.model.address.AddressOverflowException; @@ -215,4 +214,74 @@ public class DBTraceDisassemblerIntegrationTest extends AbstractGhidraHeadlessIn 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()); + } + } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/DisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/DisassembleCommand.java index 9521ec3ece..9d5ddddad0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/DisassembleCommand.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/DisassembleCommand.java @@ -20,8 +20,7 @@ import ghidra.framework.cmd.BackgroundCommand; import ghidra.framework.model.DomainObject; import ghidra.program.disassemble.*; import ghidra.program.model.address.*; -import ghidra.program.model.lang.Register; -import ghidra.program.model.lang.RegisterValue; +import ghidra.program.model.lang.*; import ghidra.program.model.listing.*; import ghidra.program.model.mem.Memory; 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 protected boolean disassemblyPerformed; // if true don't report start problems + protected String languageError; // non-null to indicate unsupported language protected boolean unalignedStart; protected boolean nonExecutableStart; /** * Constructor for DisassembleCommand. + * * @param start Address to start disassembly. - * @param restrictedSet addresses that can be disassembled. - * a null set implies no restrictions + * @param restrictedSet addresses that can be disassembled. a null set implies no restrictions * @param followFlow true means the disassembly should follow flow */ public DisassembleCommand(Address start, AddressSetView restrictedSet, boolean followFlow) { @@ -62,22 +62,22 @@ public class DisassembleCommand extends BackgroundCommand { } /** - * 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 restrictedSet addresses that can be disassembled. - * a null set implies no restrictions - */ + * 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 restrictedSet addresses that can be disassembled. a null set implies no restrictions + */ public DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet) { this(startSet, restrictedSet, true); } /** * 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 restrictedSet addresses that can be disassembled. - * a null set implies no restrictions + * + * @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 restrictedSet addresses that can be disassembled. a null set implies no restrictions */ public DisassembleCommand(AddressSetView startSet, AddressSetView restrictedSet, boolean followFlow) { @@ -93,11 +93,12 @@ public class DisassembleCommand extends BackgroundCommand { } /** - * Allows the disassembler context to be seeded for the various disassembly start - * points which may be encountered using the future flow state of the specified seedContext. - * Any initial context set via the {@link #setInitialContext(RegisterValue)} method will take - * precedence when combined with any seed values. - * The seedContext should remain unchanged while disassembler command is actively running. + * Allows the disassembler context to be seeded for the various disassembly start points which + * may be encountered using the future flow state of the specified seedContext. Any initial + * context set via the {@link #setInitialContext(RegisterValue)} method will take precedence + * when combined with any seed values. The seedContext should remain unchanged while + * disassembler command is actively running. + * * @param seedContext seed context or null */ 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 - * {@link #setSeedContext(DisassemblerContextImpl)} method. - * The defaultSeedContext should remain unchanged while disassembler command - * is actively running. + * {@link #setSeedContext(DisassemblerContextImpl)} method. The defaultSeedContext should remain + * unchanged while disassembler command is actively running. + * * @param initialContextValue the initial context value to set or null to clear it */ public void setInitialContext(RegisterValue initialContextValue) { @@ -121,8 +122,9 @@ public class DisassembleCommand extends BackgroundCommand { } /** - * Set code analysis enablement. By default new instructions will be - * submitted for auto-analysis. + * Set code analysis enablement. By default new instructions will be submitted for + * auto-analysis. + * * @param enable */ public void enableCodeAnalysis(boolean enable) { @@ -134,6 +136,9 @@ public class DisassembleCommand extends BackgroundCommand { if (disassemblyPerformed) { return null; } + if (languageError != null) { + return "The program's language is not supported: " + languageError; + } if (nonExecutableStart) { return "Disassembly of non-executable memory is disabled"; } @@ -312,7 +317,7 @@ public class DisassembleCommand extends BackgroundCommand { * * @param disassembler disassembler to use * @param seedSet set of addresses to be disassembled - * @param mgr + * @param mgr * * @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 - * data regions when performing static disassembly over a contiguous range if - * addresses. This method attemps to identify this situation by checking the first - * range of disassembledSet against the startSet. Analysis will be triggered if - * startSet contains both the max address of the first range of disassembledSet - * (M where M=disassembledSet.firstRange().getMaxAddress()) and the next address - * (M.next()) which will be the next seed point. + * Determine if intermediate analysis is required to reduce the risk of disassembling data + * regions when performing static disassembly over a contiguous range if addresses. This method + * attemps to identify this situation by checking the first range of disassembledSet against the + * startSet. Analysis will be triggered if startSet contains both the max address of the first + * range of disassembledSet (M where M=disassembledSet.firstRange().getMaxAddress()) and the + * next address (M.next()) which will be the next seed point. + * * @param mgr auto analysis manager or null if analysis disabled * @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, AddressSetView disassembledSet, TaskMonitor monitor) { @@ -366,6 +372,7 @@ public class DisassembleCommand extends BackgroundCommand { /** * Returns an address set of all instructions that were disassembled. + * * @return an address set of all instructions that were disassembled */ public AddressSet getDisassembledAddressSet() { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/X86_64DisassembleCommand.java b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/X86_64DisassembleCommand.java new file mode 100644 index 0000000000..9037dfbe6e --- /dev/null +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/cmd/disassemble/X86_64DisassembleCommand.java @@ -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 + * + *

+ * 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. + * + *

+ * WARNING: 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); + } +} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/DisassemblerPlugin.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/DisassemblerPlugin.java index 678c49bdea..29e65d12c1 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/DisassemblerPlugin.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/DisassemblerPlugin.java @@ -34,22 +34,19 @@ import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramSelection; /** - * DisassemblerPlugin provides functionality for dynamic disassembly, - * static disassembly.
- * In dynamic disassembly disassembling begins from the - * selected addresses or if there is no selection then at the address of the - * current cursor location and attempts to continue disassembling - * through fallthroughs and along all flows from a disassembled instruction. - * For instance, if a jump instruction is disassembled then the address being - * jumped to will be disassembled. The dynamic disassembly will also follow - * data pointers to addresses containing undefined data, which is then - * disassembled.
- * 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.
+ * DisassemblerPlugin provides functionality for dynamic disassembly, static + * disassembly.
+ * In dynamic disassembly disassembling begins from the selected addresses or if there is no + * selection then at the address of the current cursor location and attempts to continue + * disassembling through fallthroughs and along all flows from a disassembled instruction. For + * instance, if a jump instruction is disassembled then the address being jumped to will be + * disassembled. The dynamic disassembly will also follow data pointers to addresses containing + * undefined data, which is then disassembled.
+ * 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.
*

- * DisassemblerPlugin provides access to its functions as a service - * that another plugin may use and through the popup menu to the user. + * DisassemblerPlugin provides access to its functions as a service that another plugin + * may use and through the popup menu to the user. */ //@formatter:off @PluginInfo( @@ -89,6 +86,8 @@ public class DisassemblerPlugin extends Plugin { private DockingAction mips16DisassembleAction; private DockingAction ppcDisassembleAction; private DockingAction ppcVleDisassembleAction; + private DockingAction x86_64DisassembleAction; + private DockingAction x86_32DisassembleAction; private DockingAction setFlowOverrideAction; /** 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 - * it will work in. + * Creates a new instance of the plugin giving it the tool that it will work in. */ public DisassemblerPlugin(PluginTool tool) { super(tool); @@ -177,6 +175,8 @@ public class DisassemblerPlugin extends Plugin { mips16DisassembleAction = new MipsDisassembleAction(this, GROUP_NAME, true); ppcDisassembleAction = new PowerPCDisassembleAction(this, GROUP_NAME, false); 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); tool.addAction(disassembleAction); @@ -190,6 +190,8 @@ public class DisassemblerPlugin extends Plugin { tool.addAction(mips16DisassembleAction); tool.addAction(ppcDisassembleAction); tool.addAction(ppcVleDisassembleAction); + tool.addAction(x86_64DisassembleAction); + tool.addAction(x86_32DisassembleAction); tool.addAction(contextAction); tool.addAction(setFlowOverrideAction); } @@ -244,7 +246,8 @@ public class DisassemblerPlugin extends Plugin { try { currentProgram.getMemory().getByte(addr); AddressSetView restrictedSet = null; - if (isDynamicListing) { + // I believe this is deprecated + /*if (isDynamicListing) { // TODO: should we have option to control restricted range? Address min, max; try { @@ -260,7 +263,7 @@ public class DisassemblerPlugin extends Plugin { max = addr.getAddressSpace().getMaxAddress(); } restrictedSet = new AddressSet(min, max); - } + }*/ cmd = new DisassembleCommand(addr, restrictedSet, true); } 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); + } + } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/X86_64DisassembleAction.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/X86_64DisassembleAction.java new file mode 100644 index 0000000000..04eac18b94 --- /dev/null +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/disassembler/X86_64DisassembleAction.java @@ -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); + } +} diff --git a/Ghidra/Processors/x86/data/languages/adx.sinc b/Ghidra/Processors/x86/data/languages/adx.sinc index e8cea4a36f..1612b3896c 100644 --- a/Ghidra/Processors/x86/data/languages/adx.sinc +++ b/Ghidra/Processors/x86/data/languages/adx.sinc @@ -7,7 +7,7 @@ } @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); tmpCF:1 = tmp(8); # just the carry byte CF = tmpCF != 0; @@ -24,7 +24,7 @@ } @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); tmpOF:1 = tmp(8); # just the carry byte OF = tmpOF != 0; diff --git a/Ghidra/Processors/x86/data/languages/avx.sinc b/Ghidra/Processors/x86/data/languages/avx.sinc index b68169dc9c..7c0594c308 100644 --- a/Ghidra/Processors/x86/data/languages/avx.sinc +++ b/Ghidra/Processors/x86/data/languages/avx.sinc @@ -684,7 +684,7 @@ define pcodeop vcvtsd2si_avx ; # CVTSD2SI 3-253 PAGE 823 LINE 44317 @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 ); } @@ -710,7 +710,7 @@ define pcodeop vcvtsi2sd_avx ; # CVTSI2SD 3-257 PAGE 827 LINE 44519 @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 ); YmmReg1 = zext(tmp); @@ -729,7 +729,7 @@ define pcodeop vcvtsi2ss_avx ; # CVTSI2SS 3-259 PAGE 829 LINE 44634 @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 ); YmmReg1 = zext(tmp); @@ -756,7 +756,7 @@ define pcodeop vcvtss2si_avx ; # CVTSS2SI 3-263 PAGE 833 LINE 44837 @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 ); } @@ -805,7 +805,7 @@ define pcodeop vcvttsd2si_avx ; # CVTTSD2SI 3-274 PAGE 844 LINE 45382 @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 ); } @@ -821,7 +821,7 @@ define pcodeop vcvttss2si_avx ; # CVTTSS2SI 3-276 PAGE 846 LINE 45476 @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 ); } @@ -1186,7 +1186,7 @@ define pcodeop vmovd_avx ; # MOVD/MOVQ 4-55 PAGE 1175 LINE 61360 define pcodeop vmovq_avx ; @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 ); YmmReg1 = zext(tmp); @@ -1202,7 +1202,7 @@ define pcodeop vmovq_avx ; # MOVD/MOVQ 4-55 PAGE 1175 LINE 61364 @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 ); } @@ -1947,7 +1947,7 @@ define pcodeop vpextrd_avx ; # PEXTRB/PEXTRD/PEXTRQ 4-274 PAGE 1394 LINE 72330 define pcodeop vpextrq_avx ; @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 ); } @@ -2052,7 +2052,7 @@ define pcodeop vpinsrd_avx ; # PINSRB/PINSRD/PINSRQ 4-293 PAGE 1413 LINE 73327 define pcodeop vpinsrq_avx ; @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 ); YmmReg1 = zext(tmp); diff --git a/Ghidra/Processors/x86/data/languages/avx2_manual.sinc b/Ghidra/Processors/x86/data/languages/avx2_manual.sinc index 55f7244a65..221b22ba62 100644 --- a/Ghidra/Processors/x86/data/languages/avx2_manual.sinc +++ b/Ghidra/Processors/x86/data/languages/avx2_manual.sinc @@ -33,7 +33,7 @@ define pcodeop vgatherdpd ; # VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106908 @ifdef IA64 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 # XmmReg1 = vgatherqpd(XmmReg1, q_vm64x, vexVVVV_XmmReg); local tmp:16 = vgatherqpd(XmmReg1, vexVVVV_XmmReg); @@ -54,7 +54,7 @@ define pcodeop vgatherqpd ; # VGATHERDPD/VGATHERQPD 5-251 PAGE 2075 LINE 106918 @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 # YmmReg1 = vgatherqpd(YmmReg1, q_vm64y, vexVVVV_YmmReg); YmmReg1 = vgatherqpd(YmmReg1, vexVVVV_YmmReg); @@ -78,7 +78,7 @@ define pcodeop vgatherdps ; # VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107135 @ifdef IA64 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 # XmmReg1 = vgatherqps(XmmReg1, d_vm64x, vexVVVV_XmmReg); local tmp:16 = vgatherqps(XmmReg1, vexVVVV_XmmReg); @@ -99,7 +99,7 @@ define pcodeop vgatherqps ; # VGATHERDPS/VGATHERQPS 5-256 PAGE 2080 LINE 107145 @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 # XmmReg1 = vgatherqps(XmmReg1, d_vm64y, vexVVVV_XmmReg); XmmReg1 = vgatherqps(XmmReg1, vexVVVV_XmmReg); @@ -133,7 +133,7 @@ define pcodeop vpgatherdd ; # VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107888 @ifdef IA64 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 # XmmReg1 = vpgatherqd(XmmReg1, d_vm64x, vexVVVV_XmmReg); local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg); @@ -154,7 +154,7 @@ define pcodeop vpgatherqd ; # VPGATHERDD/VPGATHERQD 5-273 PAGE 2097 LINE 107896 @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 # XmmReg1 = vpgatherqd(XmmReg1, d_vm64y, vexVVVV_XmmReg); local tmp:16 = vpgatherqd(XmmReg1, vexVVVV_XmmReg); @@ -179,7 +179,7 @@ define pcodeop vpgatherdq ; # VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108238 @ifdef IA64 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 # XmmReg1 = vpgatherqq(XmmReg1, q_vm64x, vexVVVV_XmmReg); local tmp:16 = vpgatherqq(XmmReg1, vexVVVV_XmmReg); @@ -200,7 +200,7 @@ define pcodeop vpgatherqq ; # VPGATHERDQ/VPGATHERQQ 5-280 PAGE 2104 LINE 108246 @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 # YmmReg1 = vpgatherqq(YmmReg1, q_vm64y, vexVVVV_YmmReg); YmmReg1 = vpgatherqq(YmmReg1, vexVVVV_YmmReg); diff --git a/Ghidra/Processors/x86/data/languages/bmi1.sinc b/Ghidra/Processors/x86/data/languages/bmi1.sinc index 3c10e86cb4..561711ff79 100644 --- a/Ghidra/Processors/x86/data/languages/bmi1.sinc +++ b/Ghidra/Processors/x86/data/languages/bmi1.sinc @@ -21,7 +21,7 @@ macro tzcntflags(input, output) { @ifdef IA64 # 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; resultflags(Reg64); @@ -46,7 +46,7 @@ macro tzcntflags(input, output) { } @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]; lengthTmp:1 = vexVVVV_r64[8,8]; @@ -74,7 +74,7 @@ macro tzcntflags(input, output) { } @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; @@ -100,7 +100,7 @@ macro tzcntflags(input, output) { } @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); vexVVVV_r64 = (rm64 - 1) ^ rm64; @@ -126,7 +126,7 @@ macro tzcntflags(input, output) { } @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); vexVVVV_r64 = (rm64 - 1) & rm64; @@ -176,7 +176,7 @@ macro tzcntflags(input, output) { } @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; inputTmp:8 = rm64; diff --git a/Ghidra/Processors/x86/data/languages/bmi2.sinc b/Ghidra/Processors/x86/data/languages/bmi2.sinc index 34114bf347..3ac2841a39 100644 --- a/Ghidra/Processors/x86/data/languages/bmi2.sinc +++ b/Ghidra/Processors/x86/data/languages/bmi2.sinc @@ -22,7 +22,7 @@ } @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; @@ -52,7 +52,7 @@ } @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); @@ -85,7 +85,7 @@ } @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; @@ -128,7 +128,7 @@ } @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; resultTmp:8 = 0; @@ -157,7 +157,7 @@ } @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); @@ -173,7 +173,7 @@ } @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); } @@ -187,7 +187,7 @@ } @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); } @@ -201,7 +201,7 @@ } @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); } diff --git a/Ghidra/Processors/x86/data/languages/cet.sinc b/Ghidra/Processors/x86/data/languages/cet.sinc index 4340355fd0..ea707de8d5 100644 --- a/Ghidra/Processors/x86/data/languages/cet.sinc +++ b/Ghidra/Processors/x86/data/languages/cet.sinc @@ -16,7 +16,7 @@ define pcodeop ShadowStackLoad4B; SSP = SSP + zext(4 * r32:1); } @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); } @endif @@ -25,7 +25,7 @@ define pcodeop ShadowStackLoad4B; r32 = SSP:4; } @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; } @endif @@ -50,7 +50,7 @@ define pcodeop writeToUserShadowStack; writeToShadowStack(rm32, Reg32); } @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); } @endif @@ -59,7 +59,7 @@ define pcodeop writeToUserShadowStack; writeToUserShadowStack(rm32, Reg32); } @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); } @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 {} @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 diff --git a/Ghidra/Processors/x86/data/languages/clwb.sinc b/Ghidra/Processors/x86/data/languages/clwb.sinc index ca201e07b8..72195f8ba7 100644 --- a/Ghidra/Processors/x86/data/languages/clwb.sinc +++ b/Ghidra/Processors/x86/data/languages/clwb.sinc @@ -5,7 +5,7 @@ define pcodeop clwb; @ifdef IA64 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); } @endif diff --git a/Ghidra/Processors/x86/data/languages/ia.sinc b/Ghidra/Processors/x86/data/languages/ia.sinc index 1e633cc2fd..bd75066b21 100644 --- a/Ghidra/Processors/x86/data/languages/ia.sinc +++ b/Ghidra/Processors/x86/data/languages/ia.sinc @@ -260,40 +260,46 @@ define register offset=0x2000 size=4 contextreg; define context contextreg @ifdef IA64 - addrsize=(0,1) # =0 16-bit addressing =1 32-bit addressing =2 64-bit addressing + # Stored context + longMode=(0,0) # 0 for 32-bit emulation, 1 for 64-bit mode + reserved=(1,3) + # End stored context + addrsize=(4,5) # =0 16-bit addressing =1 32-bit addressing =2 64-bit addressing @else - addrsize=(1,1) # =0 16-bit addressing =1 32-bit addressing + # Stored context + reserved=(0,3) + # End stored context + addrsize=(5,5) # =0 16-bit addressing =1 32-bit addressing @endif - bit64=(0,0) # =0 16/32 bit =1 64-bit - opsize=(2,3) # =0 16-bit operands =1 32-bit operands =2 64-bit operands - segover=(4,6) # 0=default 1=cs 2=ss 3=ds 4=es 5=fs 6=gs - highseg=(4,4) # high bit of segover will be set for ES, FS, GS - protectedMode=(7,7) # 0 for real mode, 1 for protected mode + bit64=(4,4) # =0 16/32 bit =1 64-bit + opsize=(6,7) # =0 16-bit operands =1 32-bit operands =2 64-bit operands + segover=(8,10) # 0=default 1=cs 2=ss 3=ds 4=es 5=fs 6=gs + highseg=(8,8) # high bit of segover will be set for ES, FS, GS + protectedMode=(11,11) # 0 for real mode, 1 for protected mode - repneprefx=(8,8) # 0xf2 REPNE prefix - repprefx=(9,9) # 0xf3 REP prefix - prefix_66=(10,10) # This is not really a OPSIZE override, it means there is an real(read)/implied(vex) 66 byte - prefix_f3=(9,9) # This is not really a REP override, it means there is an real(read)/implied(vex) f3 byte - prefix_f2=(8,8) # This is not really a REPNE override, it means there is a real(read)/implied(vex) f2 byte - mandover=(8,10) # 0x66 0xf2 or 0xf3 overrides (for mandatory prefixes) + repneprefx=(12,12) # 0xf2 REPNE prefix + repprefx=(13,13) # 0xf3 REP prefix + prefix_66=(14,14) # This is not really a OPSIZE override, it means there is an real(read)/implied(vex) 66 byte + prefix_f3=(13,13) # This is not really a REP override, it means there is an real(read)/implied(vex) f3 byte + prefix_f2=(12,12) # This is not really a REPNE override, it means there is a real(read)/implied(vex) f2 byte + mandover=(12,14) # 0x66 0xf2 or 0xf3 overrides (for mandatory prefixes) - rexWprefix=(11,11) # REX.W bit prefix (opsize=2 when REX.W is set) - rexRprefix=(12,12) # REX.R bit prefix extend r - rexXprefix=(13,13) # REX.X bit prefix extend SIB index field to 4 bits - rexBprefix=(14,14) # REX.B bit prefix extend r/m, SIB base, Reg operand - rexprefix=(15,15) # True if the Rex prefix is present - note, if present, vex_mode is not supported + rexWprefix=(15,15) # REX.W bit prefix (opsize=2 when REX.W is set) + rexRprefix=(16,16) # REX.R bit prefix extend r + rexXprefix=(17,17) # REX.X bit prefix extend SIB index field to 4 bits + rexBprefix=(18,18) # REX.B bit prefix extend r/m, SIB base, Reg operand + rexprefix=(19,19) # True if the Rex prefix is present - note, if present, vex_mode is not supported # rexWRXB bits can be re-used since they are incompatible. - vexMode=(16,16) # 1 for vex instruction, 0 for normal - vexL=(17,17) # 0 for 128, 1 for 256 - vexVVVV=(18,21) # value of vex byte for matching - vexVVVV_r32=(18,21) # value of vex byte for matching a normal 32 bit register - vexVVVV_r64=(18,21) # value of vex byte for matching a normal 64 bit register - vexVVVV_XmmReg=(18,21) # value of vex byte for matching XmmReg - vexVVVV_YmmReg=(18,21) # value of vex byte for matching YmmReg - vexMMMMM=(22,26) # need to match for preceding bytes 1=0x0F, 2=0x0F 0x38, 3=0x0F 0x3A - - suffix3D=(17,24) # 3DNow suffix byte (overlaps un-modified vex context region) + vexMode=(20,20) # 1 for vex instruction, 0 for normal + vexL=(21,21) # 0 for 128, 1 for 256 + vexVVVV=(22,25) # value of vex byte for matching + vexVVVV_r32=(22,25) # value of vex byte for matching a normal 32 bit register + vexVVVV_r64=(22,25) # value of vex byte for matching a normal 64 bit register + vexVVVV_XmmReg=(22,25) # value of vex byte for matching XmmReg + vexVVVV_YmmReg=(22,25) # value of vex byte for matching YmmReg + vexMMMMM=(26,30) # need to match for preceding bytes 1=0x0F, 2=0x0F 0x38, 3=0x0F 0x3A + suffix3D=(21,28) # 3DNow suffix byte (overlaps un-modified vex context region) instrPhase=(31,31) # 0: initial/prefix phase, 1: primary instruction phase ; @@ -556,6 +562,13 @@ define pcodeop vmwrite; # Write field to virtual-machine control structure; opc define pcodeop vmxoff; # Leave VMX operation; opcode 0f 01 c4 define pcodeop vmxon; # Enter VMX operation; opcode f3 0f C7 /6 +@ifdef IA64 +@define LONGMODE_ON "longMode=1" +@define LONGMODE_OFF "longMode=0" +@else +@define LONGMODE_OFF "opsize=opsize" # NOP +@endif + @ifdef IA64 Reg8: reg8 is rexprefix=0 & reg8 { export reg8; } Reg8: reg8_x0 is rexprefix=1 & rexRprefix=0 & reg8_x0 { export reg8_x0; } @@ -760,15 +773,16 @@ Mem16: addr16 is (segover=0 & mod=2 & r_m=6) ... & addr16 { tmp:$(SIZE) = se Mem16: seg16^addr16 is seg16; addr16 { tmp:$(SIZE) = segment(seg16,addr16); export tmp; } Mem: Mem16 is addrsize=0 & Mem16 { export Mem16; } + @ifdef IA64 -Mem: segWide^Addr32_64 is addrsize=1 & segWide; Addr32_64 { export Addr32_64; } -Mem: segWide^Addr32_64 is addrsize=1 & segWide & highseg=1; Addr32_64 { tmp:8 = segWide + Addr32_64; export tmp; } -Mem: segWide^addr64 is addrsize=2 & segWide; addr64 { export addr64; } -Mem: segWide^addr64 is addrsize=2 & segWide & highseg=1; addr64 { tmp:$(SIZE) = segWide + addr64; export tmp; } -@else -Mem: segWide^addr32 is addrsize=1 & segWide; addr32 { export addr32; } -Mem: segWide^addr32 is addrsize=1 & segWide & highseg=1; addr32 { tmp:$(SIZE) = segWide + addr32; export tmp; } +Mem: segWide^Addr32_64 is $(LONGMODE_ON) & addrsize=1 & segWide; Addr32_64 { export Addr32_64; } +Mem: segWide^Addr32_64 is $(LONGMODE_ON) & addrsize=1 & segWide & highseg=1; Addr32_64 { tmp:8 = segWide + Addr32_64; export tmp; } +Mem: segWide^addr64 is $(LONGMODE_ON) & addrsize=2 & segWide; addr64 { export addr64; } +Mem: segWide^addr64 is $(LONGMODE_ON) & addrsize=2 & segWide & highseg=1; addr64 { tmp:$(SIZE) = segWide + addr64; export tmp; } @endif +# TODO: It'd be nice if we could use 32-bit pointers in the 64-bit spec outside of long mode +Mem: segWide^addr32 is $(LONGMODE_OFF) & addrsize=1 & segWide; addr32 { tmp:$(SIZE) = zext(addr32); export tmp; } +Mem: segWide^addr32 is $(LONGMODE_OFF) & addrsize=1 & segWide & highseg=1; addr32 { tmp:$(SIZE) = segWide + zext(addr32); export tmp; } rel8: reloc is simm8 [ reloc=inst_next+simm8; ] { export *[ram]:$(SIZE) reloc; } rel16: reloc is simm16 [ reloc=((inst_next >> 16) << 16) | ((inst_next + simm16) & 0xFFFF); ] { export *[ram]:$(SIZE) reloc; } @@ -1471,7 +1485,7 @@ macro fucompe(val1, val2) { AF = 0; SF = 0; } - + # The base level constructors # The prefixes :^instruction is instrPhase=0 & over=0x2e; instruction [ segover=1; ] {} # CS override @@ -1492,21 +1506,25 @@ macro fucompe(val1, val2) { # REX prefix present # Specification is "REX" -@define REX "rexprefix=1 & rexWprefix=0" +@define REX "longMode=1 & rexprefix=1 & rexWprefix=0" # Specification is "REX.W" -@define REX_W "rexprefix=1 & rexWprefix=1" +@define REX_W "longMode=1 & rexprefix=1 & rexWprefix=1" # TODO I don't think the following line can really happen because the 66 67 prefix must come before REX prefix -:^instruction is instrPhase=0 & over=0x66 & opsize=2; instruction [ opsize=0; mandover=mandover $xor 1; ] {} # Operand size override -:^instruction is instrPhase=0 & over=0x67 & addrsize=2; instruction [ addrsize=1; ] {} # Address size override +:^instruction is $(LONGMODE_ON) & instrPhase=0 & over=0x66 & opsize=2; instruction [ opsize=0; mandover=mandover $xor 1; ] {} # Operand size override +:^instruction is $(LONGMODE_ON) & instrPhase=0 & over=0x67 & addrsize=2; instruction [ addrsize=1; ] {} # Address size override -:^instruction is instrPhase=0 & row=0x4 & rexw=0 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=1; rexWprefix=0; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} -:^instruction is instrPhase=0 & row=0x4 & rexw=1 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=2; rexWprefix=1; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} -:^instruction is instrPhase=0 & opsize=0 & row=0x4 & rexw=0 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=0; rexWprefix=0; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} -:^instruction is instrPhase=0 & opsize=0 & row=0x4 & rexw=1 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=2; rexWprefix=1; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & row=0x4 & rexw=0 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=1; rexWprefix=0; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & row=0x4 & rexw=1 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=2; rexWprefix=1; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & opsize=0 & row=0x4 & rexw=0 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=0; rexWprefix=0; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} +:^instruction is $(LONGMODE_ON) & instrPhase=0 & opsize=0 & row=0x4 & rexw=1 & rexr & rexx & rexb; instruction [ instrPhase=1; rexprefix=1; opsize=2; rexWprefix=1; rexRprefix=rexr; rexXprefix=rexx; rexBprefix=rexb; ] {} + + # if longmode is off (on 64-bit processor in 32-bit compatibility mode), there is no 64-bit addressing, make sure is off before parsing + # +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & addrsize=2 & instruction [ addrsize=1; ] {} @endif # @@ -1550,48 +1568,47 @@ macro fucompe(val1, val2) { @ifdef IA64 # 64-bit 3-byte VEX -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=0; instruction +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=0; instruction [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; rexXprefix=~vex_x; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=1; instruction +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=1; instruction [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; rexXprefix=~vex_x; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_66=1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=2; instruction +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=2; instruction [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; rexXprefix=~vex_x; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_f3=1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=3; instruction +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r & vex_x & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=3; instruction [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; rexXprefix=~vex_x; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_f2=1; ] {} # 64-bit 2-byte VEX -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=0; instruction +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=0; instruction [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=1; instruction +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=1; instruction [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_66=1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=2; instruction +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=2; instruction [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_f3=1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=3; instruction +:^instruction is $(LONGMODE_ON) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r & vex_vvvv & vex_l & vex_pp=3; instruction [ instrPhase=1; vexMode=1; rexRprefix=~vex_r; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_f2=1; ] {} -@else +@endif # 32-bit 3-byte VEX -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=0; instruction +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=0; instruction [ instrPhase=1; vexMode=1; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=1; instruction +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=1; instruction [ instrPhase=1; vexMode=1; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_66=1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=2; instruction +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=2; instruction [ instrPhase=1; vexMode=1; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_f3=1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=3; instruction +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC4; vex_r=1 & vex_x=1 & vex_b & vex_mmmmm; vex_w & vex_vvvv & vex_l & vex_pp=3; instruction [ instrPhase=1; vexMode=1; rexBprefix=~vex_b; vexMMMMM=vex_mmmmm; rexWprefix=vex_w; vexVVVV=~vex_vvvv; vexL=vex_l; prefix_f2=1; ] {} # 32-bit 2-byte VEX -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_vvvv & vex_l & vex_pp=0; instruction +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_vvvv & vex_l & vex_pp=0; instruction [ instrPhase=1; vexMode=1; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_vvvv & vex_l & vex_pp=1; instruction +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_vvvv & vex_l & vex_pp=1; instruction [ instrPhase=1; vexMode=1; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_66=1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_vvvv & vex_l & vex_pp=2; instruction +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_vvvv & vex_l & vex_pp=2; instruction [ instrPhase=1; vexMode=1; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_f3=1; ] {} -:^instruction is instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_vvvv & vex_l & vex_pp=3; instruction +:^instruction is $(LONGMODE_OFF) & instrPhase=0 & vexMode=0 & rexprefix=0 & mandover=0 & byte=0xC5; vex_r=1 & vex_vvvv & vex_l & vex_pp=3; instruction [ instrPhase=1; vexMode=1; vexVVVV=~vex_vvvv; vexL=vex_l; vexMMMMM=0x1; prefix_f2=1; ] {} -@endif # Many of the multimedia instructions have a "mandatory" prefix, either 0x66, 0xf2 or 0xf3 # where the prefix really becomes part of the encoding. We collect the three possible prefixes of this @@ -1619,97 +1636,95 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { } :ADC AX,imm16 is vexMode=0 & opsize=0 & byte=0x15; AX & imm16 { addCarryFlags( AX, imm16:2 ); resultflags( AX ); } :ADC EAX,imm32 is vexMode=0 & opsize=1 & byte=0x15; EAX & check_EAX_dest & imm32 { addCarryFlags( EAX, imm32:4 ); build check_EAX_dest; resultflags( EAX ); } @ifdef IA64 -:ADC RAX,simm32 is vexMode=0 & opsize=2 & byte=0x15; RAX & simm32 { addCarryFlags( RAX, simm32 ); resultflags( RAX ); } +:ADC RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x15; RAX & simm32 { addCarryFlags( RAX, simm32 ); resultflags( RAX ); } @endif :ADC spec_rm8,imm8 is vexMode=0 & (byte=0x80 | byte=0x82); spec_rm8 & reg_opcode=2 ... ; imm8 { addCarryFlags( spec_rm8, imm8:1 ); resultflags( spec_rm8 ); } :ADC spec_rm16,imm16 is vexMode=0 & opsize=0 & byte=0x81; spec_rm16 & reg_opcode=2 ...; imm16 { addCarryFlags( spec_rm16, imm16:2 ); resultflags( spec_rm16 ); } :ADC spec_rm32,imm32 is vexMode=0 & opsize=1 & byte=0x81; spec_rm32 & check_rm32_dest ... & reg_opcode=2 ...; imm32 { addCarryFlags( spec_rm32, imm32:4 ); build check_rm32_dest; resultflags( spec_rm32 ); } @ifdef IA64 -:ADC spec_rm64,simm32 is vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=2 ...; simm32 { addCarryFlags( spec_rm64, simm32 ); resultflags( spec_rm64 ); } +:ADC spec_rm64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=2 ...; simm32 { addCarryFlags( spec_rm64, simm32 ); resultflags( spec_rm64 ); } @endif :ADC spec_rm16,simm8_16 is vexMode=0 & opsize=0 & byte=0x83; spec_rm16 & reg_opcode=2 ...; simm8_16 { addCarryFlags( spec_rm16, simm8_16 ); resultflags( spec_rm16 ); } :ADC spec_rm32,simm8_32 is vexMode=0 & opsize=1 & byte=0x83; spec_rm32 & check_rm32_dest ... & reg_opcode=2 ...; simm8_32 { addCarryFlags( spec_rm32, simm8_32 ); build check_rm32_dest; resultflags( spec_rm32 ); } @ifdef IA64 -:ADC spec_rm64,simm8_64 is vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=2 ...; simm8_64 { addCarryFlags( spec_rm64, simm8_64 ); resultflags( spec_rm64 ); } +:ADC spec_rm64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=2 ...; simm8_64 { addCarryFlags( spec_rm64, simm8_64 ); resultflags( spec_rm64 ); } @endif :ADC rm8,Reg8 is vexMode=0 & byte=0x10; rm8 & Reg8 ... { addCarryFlags( rm8, Reg8 ); resultflags( rm8 ); } :ADC rm16,Reg16 is vexMode=0 & opsize=0 & byte=0x11; rm16 & Reg16 ... { addCarryFlags( rm16, Reg16 ); resultflags( rm16 ); } :ADC rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x11; rm32 & check_rm32_dest ... & Reg32 ... { addCarryFlags( rm32, Reg32 ); build check_rm32_dest; resultflags( rm32 ); } @ifdef IA64 -:ADC rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x11; rm64 & Reg64 ... { addCarryFlags( rm64, Reg64 ); resultflags( rm64 ); } +:ADC rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x11; rm64 & Reg64 ... { addCarryFlags( rm64, Reg64 ); resultflags( rm64 ); } @endif :ADC Reg8,rm8 is vexMode=0 & byte=0x12; rm8 & Reg8 ... { addCarryFlags( Reg8, rm8 ); resultflags( Reg8 ); } :ADC Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x13; rm16 & Reg16 ... { addCarryFlags( Reg16, rm16 ); resultflags( Reg16 ); } :ADC Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x13; rm32 & Reg32 ... & check_Reg32_dest ... { addCarryFlags( Reg32, rm32 ); build check_Reg32_dest; resultflags( Reg32 ); } @ifdef IA64 -:ADC Reg64,rm64 is vexMode=0 & opsize=2 & byte=0x13; rm64 & Reg64 ... { addCarryFlags( Reg64, rm64 ); resultflags( Reg64 ); } +:ADC Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x13; rm64 & Reg64 ... { addCarryFlags( Reg64, rm64 ); resultflags( Reg64 ); } @endif :ADD AL,imm8 is vexMode=0 & byte=0x4; AL & imm8 { addflags( AL,imm8 ); AL = AL + imm8; resultflags( AL); } :ADD AX,imm16 is vexMode=0 & opsize=0 & byte=0x5; AX & imm16 { addflags( AX,imm16); AX = AX + imm16; resultflags( AX); } :ADD EAX,imm32 is vexMode=0 & opsize=1 & byte=0x5; EAX & check_EAX_dest & imm32 { addflags( EAX,imm32); EAX = EAX + imm32; build check_EAX_dest; resultflags( EAX); } @ifdef IA64 -:ADD RAX,simm32 is vexMode=0 & opsize=2 & byte=0x5; RAX & simm32 { addflags( RAX,simm32); RAX = RAX + simm32; resultflags( RAX); } +:ADD RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x5; RAX & simm32 { addflags( RAX,simm32); RAX = RAX + simm32; resultflags( RAX); } @endif :ADD spec_rm8,imm8 is vexMode=0 & (byte=0x80 | byte=0x82); spec_rm8 & reg_opcode=0 ...; imm8 { addflags( spec_rm8,imm8 ); spec_rm8 = spec_rm8 + imm8; resultflags( spec_rm8); } :ADD spec_rm16,imm16 is vexMode=0 & opsize=0 & byte=0x81; spec_rm16 & reg_opcode=0 ...; imm16 { addflags( spec_rm16,imm16); spec_rm16 = spec_rm16 + imm16; resultflags( spec_rm16); } :ADD spec_rm32,imm32 is vexMode=0 & opsize=1 & byte=0x81; spec_rm32 & check_rm32_dest ... & reg_opcode=0 ...; imm32 { addflags( spec_rm32,imm32); spec_rm32 = spec_rm32 + imm32; build check_rm32_dest; resultflags( spec_rm32); } @ifdef IA64 -:ADD spec_rm64,simm32 is vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=0 ...; simm32 { addflags( spec_rm64,simm32); spec_rm64 = spec_rm64 + simm32; resultflags( spec_rm64); } +:ADD spec_rm64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=0 ...; simm32 { addflags( spec_rm64,simm32); spec_rm64 = spec_rm64 + simm32; resultflags( spec_rm64); } @endif :ADD spec_rm16,simm8_16 is vexMode=0 & opsize=0 & byte=0x83; spec_rm16 & reg_opcode=0 ...; simm8_16 { addflags( spec_rm16,simm8_16); spec_rm16 = spec_rm16 + simm8_16; resultflags( spec_rm16); } :ADD spec_rm32,simm8_32 is vexMode=0 & opsize=1 & byte=0x83; spec_rm32 & check_rm32_dest ... & reg_opcode=0 ...; simm8_32 { addflags( spec_rm32,simm8_32); spec_rm32 = spec_rm32 + simm8_32; build check_rm32_dest; resultflags( spec_rm32); } @ifdef IA64 -:ADD spec_rm64,simm8_64 is vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=0 ...; simm8_64 { addflags( spec_rm64,simm8_64); spec_rm64 = spec_rm64 + simm8_64; resultflags( spec_rm64); } +:ADD spec_rm64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=0 ...; simm8_64 { addflags( spec_rm64,simm8_64); spec_rm64 = spec_rm64 + simm8_64; resultflags( spec_rm64); } @endif :ADD rm8,Reg8 is vexMode=0 & byte=0x00; rm8 & Reg8 ... { addflags( rm8,Reg8 ); rm8 = rm8 + Reg8; resultflags( rm8); } :ADD rm16,Reg16 is vexMode=0 & opsize=0 & byte=0x1; rm16 & Reg16 ... { addflags( rm16,Reg16); rm16 = rm16 + Reg16; resultflags( rm16); } :ADD rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x1; rm32 & check_rm32_dest ... & Reg32 ... { addflags( rm32,Reg32); rm32 = rm32 + Reg32; build check_rm32_dest; resultflags( rm32); } @ifdef IA64 -:ADD rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x1; rm64 & Reg64 ... { addflags( rm64,Reg64); rm64 = rm64 + Reg64; resultflags( rm64); } +:ADD rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x1; rm64 & Reg64 ... { addflags( rm64,Reg64); rm64 = rm64 + Reg64; resultflags( rm64); } @endif :ADD Reg8,rm8 is vexMode=0 & byte=0x2; rm8 & Reg8 ... { addflags( Reg8,rm8 ); Reg8 = Reg8 + rm8; resultflags( Reg8); } :ADD Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x3; rm16 & Reg16 ... { addflags(Reg16,rm16 ); Reg16 = Reg16 + rm16; resultflags(Reg16); } :ADD Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x3; rm32 & Reg32 ... & check_Reg32_dest ... { addflags(Reg32,rm32 ); Reg32 = Reg32 + rm32; build check_Reg32_dest; resultflags(Reg32); } @ifdef IA64 -:ADD Reg64,rm64 is vexMode=0 & opsize=2 & byte=0x3; rm64 & Reg64 ... { addflags(Reg64,rm64 ); Reg64 = Reg64 + rm64; resultflags(Reg64); } +:ADD Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x3; rm64 & Reg64 ... { addflags(Reg64,rm64 ); Reg64 = Reg64 + rm64; resultflags(Reg64); } @endif :AND AL,imm8 is vexMode=0 & byte=0x24; AL & imm8 { logicalflags(); AL = AL & imm8; resultflags( AL); } :AND AX,imm16 is vexMode=0 & opsize=0 & byte=0x25; AX & imm16 { logicalflags(); AX = AX & imm16; resultflags( AX); } :AND EAX,imm32 is vexMode=0 & opsize=1 & byte=0x25; EAX & check_EAX_dest & imm32 { logicalflags(); EAX = EAX & imm32; build check_EAX_dest; resultflags( EAX); } @ifdef IA64 -:AND RAX,simm32 is vexMode=0 & opsize=2 & byte=0x25; RAX & simm32 { logicalflags(); RAX = RAX & simm32; resultflags( RAX); } +:AND RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x25; RAX & simm32 { logicalflags(); RAX = RAX & simm32; resultflags( RAX); } @endif :AND rm8,imm8 is vexMode=0 & (byte=0x80 | byte=0x82); rm8 & reg_opcode=4 ...; imm8 { logicalflags(); rm8 = rm8 & imm8; resultflags( rm8); } :AND rm16,imm16 is vexMode=0 & opsize=0 & byte=0x81; rm16 & reg_opcode=4 ...; imm16 { logicalflags(); rm16 = rm16 & imm16; resultflags( rm16); } :AND rm32,imm32 is vexMode=0 & opsize=1 & byte=0x81; rm32 & check_rm32_dest ... & reg_opcode=4 ...; imm32 { logicalflags(); rm32 = rm32 & imm32; build check_rm32_dest; resultflags( rm32); } @ifdef IA64 -:AND rm64,simm32 is vexMode=0 & opsize=2 & byte=0x81; rm64 & reg_opcode=4 ...; simm32 { logicalflags(); rm64 = rm64 & simm32; resultflags( rm64); } +:AND rm64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; rm64 & reg_opcode=4 ...; simm32 { logicalflags(); rm64 = rm64 & simm32; resultflags( rm64); } @endif :AND rm16,usimm8_16 is vexMode=0 & opsize=0 & byte=0x83; rm16 & reg_opcode=4 ...; usimm8_16 { logicalflags(); rm16 = rm16 & usimm8_16; resultflags( rm16); } :AND rm32,usimm8_32 is vexMode=0 & opsize=1 & byte=0x83; rm32 & check_rm32_dest ... & reg_opcode=4 ...; usimm8_32 { logicalflags(); rm32 = rm32 & usimm8_32; build check_rm32_dest; resultflags( rm32); } @ifdef IA64 -:AND rm64,usimm8_64 is vexMode=0 & opsize=2 & byte=0x83; rm64 & reg_opcode=4 ...; usimm8_64 { logicalflags(); rm64 = rm64 & usimm8_64; resultflags( rm64); } +:AND rm64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; rm64 & reg_opcode=4 ...; usimm8_64 { logicalflags(); rm64 = rm64 & usimm8_64; resultflags( rm64); } @endif :AND rm8,Reg8 is vexMode=0 & byte=0x20; rm8 & Reg8 ... { logicalflags(); rm8 = rm8 & Reg8; resultflags( rm8); } :AND rm16,Reg16 is vexMode=0 & opsize=0 & byte=0x21; rm16 & Reg16 ... { logicalflags(); rm16 = rm16 & Reg16; resultflags( rm16); } :AND rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x21; rm32 & check_rm32_dest ... & Reg32 ... { logicalflags(); rm32 = rm32 & Reg32; build check_rm32_dest; resultflags( rm32); } @ifdef IA64 -:AND rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x21; rm64 & Reg64 ... { logicalflags(); rm64 = rm64 & Reg64; resultflags( rm64); } +:AND rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x21; rm64 & Reg64 ... { logicalflags(); rm64 = rm64 & Reg64; resultflags( rm64); } @endif :AND Reg8,rm8 is vexMode=0 & byte=0x22; rm8 & Reg8 ... { logicalflags(); Reg8 = Reg8 & rm8; resultflags( Reg8); } :AND Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x23; rm16 & Reg16 ... { logicalflags(); Reg16 = Reg16 & rm16; resultflags(Reg16); } :AND Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x23; rm32 & Reg32 ... & check_Reg32_dest ... { logicalflags(); Reg32 = Reg32 & rm32; build check_Reg32_dest; resultflags(Reg32); } @ifdef IA64 -:AND Reg64,rm64 is vexMode=0 & opsize=2 & byte=0x23; rm64 & Reg64 ... { logicalflags(); Reg64 = Reg64 & rm64; resultflags(Reg64); } +:AND Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x23; rm64 & Reg64 ... { logicalflags(); Reg64 = Reg64 & rm64; resultflags(Reg64); } @endif -@ifndef IA64 #ARPL is not encodable in 64-bit mode -:ARPL rm16,Reg16 is vexMode=0 & bit64=0 & byte=0x63; rm16 & Reg16 ... { local rpldest=rm16&3; local rplsrc=Reg16&3; local rpldiff=rplsrc-rpldest; +:ARPL rm16,Reg16 is $(LONGMODE_OFF) & vexMode=0 & bit64=0 & byte=0x63; rm16 & Reg16 ... { local rpldest=rm16&3; local rplsrc=Reg16&3; local rpldiff=rplsrc-rpldest; ZF = rpldiff s> 0; rm16 = rm16 + (zext(CF) * rpldiff); } -@endif :BOUND Reg16,m16 is vexMode=0 & bit64=0 & opsize=0 & byte=0x62; m16 & Reg16 ... { } :BOUND Reg32,m32 is vexMode=0 & bit64=0 & opsize=1 & byte=0x62; m32 & Reg32 ... { } @@ -1813,7 +1828,7 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { } # choose = zext((mask & rm64) == 0); # Reg64 = pos + choose; } -:BSF Reg64,rm64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xbc; rm64 & Reg64 ... +:BSF Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xbc; rm64 & Reg64 ... { bitIndex:8 = 0; @@ -1931,7 +1946,7 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { } # choose = zext((mask & rm64) == 0); # Reg64 = pos - choose; } -:BSR Reg64,rm64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xbd; rm64 & Reg64 ... +:BSR Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xbd; rm64 & Reg64 ... { bitIndex:8 = 63; @@ -1957,7 +1972,7 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { } Rmr32 = tmp | ((Rmr32 & 0x000000ff) << 24); build check_Rmr32_dest; } @ifdef IA64 -:BSWAP Rmr64 is vexMode=0 & opsize=2 & byte=0xf; row=12 & page=1 & Rmr64 +:BSWAP Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; row=12 & page=1 & Rmr64 { local tmp = (Rmr64 & 0xff00000000000000) >> 56 ; tmp = tmp | ((Rmr64 & 0x00ff000000000000) >> 40 ); tmp = tmp | ((Rmr64 & 0x0000ff0000000000) >> 24 ); @@ -1981,14 +1996,14 @@ Suffix3D: imm8 is imm8 [ suffix3D=imm8; ] { } CF = ((*:1 ptr >> (Reg32 & 0x7)) & 1) != 0; } @ifdef IA64 -:BT Rmr64,Reg64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xa3; mod=3 & Rmr64 & Reg64 { CF = ((Rmr64 >> (Reg64 & 0x3f)) & 1) != 0; } -:BT Mem,Reg64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xa3; Mem & Reg64 ... { local ptr = Mem + (Reg64 s>> 3); +:BT Rmr64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xa3; mod=3 & Rmr64 & Reg64 { CF = ((Rmr64 >> (Reg64 & 0x3f)) & 1) != 0; } +:BT Mem,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xa3; Mem & Reg64 ... { local ptr = Mem + (Reg64 s>> 3); CF = ((*:1 ptr >> (Reg64 & 0x7)) & 1) != 0; } @endif :BT rm16,imm8 is vexMode=0 & opsize=0 & byte=0xf; byte=0xba; (rm16 & reg_opcode=4 ...); imm8 { CF = ((rm16 >> (imm8 & 0x0f)) & 1) != 0; } :BT rm32,imm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xba; (rm32 & reg_opcode=4 ...); imm8 { CF = ((rm32 >> (imm8 & 0x1f)) & 1) != 0; } @ifdef IA64 -:BT rm64,imm8 is vexMode=0 & opsize=2 & byte=0xf; byte=0xba; (rm64 & reg_opcode=4 ...); imm8 { CF = ((rm64 >> (imm8 & 0x3f)) & 1) != 0; } +:BT rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xba; (rm64 & reg_opcode=4 ...); imm8 { CF = ((rm64 >> (imm8 & 0x3f)) & 1) != 0; } @endif :BTC Rmr16,Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbb; mod=3 & Rmr16 & Reg16 { local bit=Reg16&0xf; local val=(Rmr16>>bit)&1; Rmr16=Rmr16^(1<>bit)&1; Rmr64=Rmr64^(1<> 3); local bit=Reg64&7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr ^ (1<>bit)&1; Rmr64=Rmr64^(1<> 3); local bit=Reg64&7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr ^ (1<>bit)&1; rm16=rm16^(1<>bit)&1; CF=(val!=0); rm32=rm32^(1<>bit)&1; rm64=rm64^(1<>bit)&1; rm64=rm64^(1<>bit)&1; Rmr16=Rmr16 & ~(1<>bit)&1; Rmr64=Rmr64 & ~(1<> 3); local bit = Reg64 & 7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr & ~(1<>bit)&1; Rmr64=Rmr64 & ~(1<> 3); local bit = Reg64 & 7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr & ~(1<>bit)&1; rm16=rm16 & ~(1<>bit)&1; CF=(val!=0); rm32=rm32 & ~(1<>bit)&1; rm64=rm64 & ~(1<>bit)&1; rm64=rm64 & ~(1<>bit)&1; Rmr16=Rmr16 | (1<>bit)&1; Rmr64=Rmr64 | (1<>3); local bit = Reg64 & 7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr | (1<>bit)&1; Rmr64=Rmr64 | (1<>3); local bit = Reg64 & 7; local val = (*:1 ptr >> bit) & 1; *:1 ptr = *:1 ptr | (1<>bit)&1; rm16=rm16 | (1<>bit)&1; CF=(val!=0); rm32=rm32 | (1<>bit)&1; rm64=rm64 | (1<>bit)&1; rm64=rm64 | (1<; @@ -2404,13 +2413,11 @@ define pcodeop cpuid_brand_part3_info; :DEC spec_rm16 is vexMode=0 & opsize=0 & byte=0xff; spec_rm16 & reg_opcode=1 ... { OF = sborrow(spec_rm16,1); spec_rm16 = spec_rm16 - 1; resultflags(spec_rm16); } :DEC spec_rm32 is vexMode=0 & opsize=1 & byte=0xff; spec_rm32 & check_rm32_dest ... & reg_opcode=1 ... { OF = sborrow(spec_rm32,1); spec_rm32 = spec_rm32 - 1; build check_rm32_dest; resultflags(spec_rm32); } @ifdef IA64 -:DEC spec_rm64 is vexMode=0 & opsize=2 & byte=0xff; spec_rm64 & reg_opcode=1 ... { OF = sborrow(spec_rm64,1); spec_rm64 = spec_rm64 - 1; resultflags(spec_rm64); } +:DEC spec_rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xff; spec_rm64 & reg_opcode=1 ... { OF = sborrow(spec_rm64,1); spec_rm64 = spec_rm64 - 1; resultflags(spec_rm64); } @endif -@ifndef IA64 -:DEC Rmr16 is vexMode=0 & opsize=0 & row=4 & page=1 & Rmr16 { OF = sborrow(Rmr16,1); Rmr16 = Rmr16 - 1; resultflags( Rmr16); } -:DEC Rmr32 is vexMode=0 & opsize=1 & row=4 & page=1 & Rmr32 & check_Rmr32_dest { OF = sborrow(Rmr32,1); Rmr32 = Rmr32 - 1; build check_Rmr32_dest; resultflags( Rmr32); } -@endif +:DEC Rmr16 is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & row=4 & page=1 & Rmr16 { OF = sborrow(Rmr16,1); Rmr16 = Rmr16 - 1; resultflags( Rmr16); } +:DEC Rmr32 is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & row=4 & page=1 & Rmr32 & check_Rmr32_dest { OF = sborrow(Rmr32,1); Rmr32 = Rmr32 - 1; build check_Rmr32_dest; resultflags( Rmr32); } :DIV rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=6 ... { rm8ext:2 = zext(rm8); local quotient = AX / rm8ext; # DE exception if quotient doesn't fit in AL @@ -2432,7 +2439,7 @@ define pcodeop cpuid_brand_part3_info; EDX = rem:4; build check_EDX_dest; } @ifdef IA64 -:DIV rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=6 ... { rm64ext:16 = zext(rm64); +:DIV rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=6 ... { rm64ext:16 = zext(rm64); tmp:16 = (zext(RDX) << 64) | zext(RAX); # DE exception if quotient doesn't fit in RAX local quotient = tmp / rm64ext; RAX = quotient:8; @@ -2443,13 +2450,13 @@ define pcodeop cpuid_brand_part3_info; enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } @ifdef IA64 -:ENTER imm16,enterFrames is vexMode=0 & addrsize=2 & byte=0xc8; imm16; enterFrames & low5=0x00 { +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xc8; imm16; enterFrames & low5=0x00 { push88(RBP); RBP = RSP; RSP = RSP - imm16; } -:ENTER imm16,enterFrames is vexMode=0 & addrsize=2 & byte=0xc8; imm16; enterFrames & low5=0x01 { +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xc8; imm16; enterFrames & low5=0x01 { push88(RBP); frameTemp:8 = RSP; @@ -2458,7 +2465,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } RSP = RSP - imm16; } -:ENTER imm16,enterFrames is vexMode=0 & addrsize=2 & opsize=2 & byte=0xc8; imm16; enterFrames { +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0xc8; imm16; enterFrames { push88(RBP); frameTemp:8 = RSP; @@ -2481,7 +2488,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } RSP = RSP - imm16; } -:ENTER imm16,enterFrames is vexMode=0 & addrsize=2 & opsize=1 & byte=0xc8; imm16; enterFrames { +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0xc8; imm16; enterFrames { push88(RBP); frameTemp:8 = RSP; @@ -2504,7 +2511,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } RSP = RSP - imm16; } -:ENTER imm16,enterFrames is vexMode=0 & addrsize=2 & opsize=0 & byte=0xc8; imm16; enterFrames { +:ENTER imm16,enterFrames is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xc8; imm16; enterFrames { push88(RBP); frameTemp:8 = RSP; @@ -2692,7 +2699,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } EDX = rem:4; build check_EDX_dest; } @ifdef IA64 -:IDIV rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=7 ... { rm64ext:16 = sext(rm64); +:IDIV rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=7 ... { rm64ext:16 = sext(rm64); tmp:16 = (zext(RDX) << 64) | zext(RAX); # DE exception if quotient doesn't fit in RAX local quotient = tmp s/ rm64ext; RAX = quotient:8; @@ -2707,7 +2714,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } EDX = tmp(4); build check_EDX_dest; EAX = tmp(0); build check_EAX_dest; imultflags(EAX,tmp); } @ifdef IA64 # We do a second multiply so emulator(s) that only have precision up to 64 bits will still get lower 64 bits correct -:IMUL rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=5 ... { tmp:16 = sext(RAX) * sext(rm64); +:IMUL rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=5 ... { tmp:16 = sext(RAX) * sext(rm64); RAX = RAX * rm64; RDX = tmp(8); imultflags(RAX,tmp); } @endif :IMUL Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0xaf; rm16 & Reg16 ... { tmp:4 = sext(Reg16) * sext(rm16); @@ -2716,7 +2723,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } Reg32 = tmp(0); high:4 = tmp(4); imultflags(Reg32,tmp); build check_Reg32_dest; } @ifdef IA64 # We do a second multiply so emulator(s) that only have precision up to 64 bits will still get lower 64 bits correct -:IMUL Reg64,rm64 is vexMode=0 & opsize=2 & byte=0xf; byte=0xaf; rm64 & Reg64 ... { tmp:16 = sext(Reg64) * sext(rm64); +:IMUL Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xaf; rm64 & Reg64 ... { tmp:16 = sext(Reg64) * sext(rm64); Reg64 = Reg64 * rm64; high:8 = tmp(8); imultflags(Reg64,tmp);} @endif :IMUL Reg16,rm16,simm8_16 is vexMode=0 & opsize=0 & byte=0x6b; (rm16 & Reg16 ...) ; simm8_16 { tmp:4 = sext(rm16) * sext(simm8_16); @@ -2725,7 +2732,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } Reg32 = tmp(0); high:4 = tmp(4); imultflags(Reg32,tmp); build check_Reg32_dest; } @ifdef IA64 # We do a second multiply so emulator(s) that only have precision up to 64 bits will still get lower 64 bits correct -:IMUL Reg64,rm64,simm8_64 is vexMode=0 & opsize=2 & byte=0x6b; (rm64 & Reg64 ...) ; simm8_64 { tmp:16 = sext(rm64) * sext(simm8_64); +:IMUL Reg64,rm64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x6b; (rm64 & Reg64 ...) ; simm8_64 { tmp:16 = sext(rm64) * sext(simm8_64); Reg64 = rm64 * simm8_64; high:8 = tmp(8); imultflags(Reg64,tmp);} @endif :IMUL Reg16,rm16,simm16_16 is vexMode=0 & opsize=0 & byte=0x69; (rm16 & Reg16 ...) ; simm16_16 { tmp:4 = sext(rm16) * sext(simm16_16); @@ -2733,7 +2740,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } :IMUL Reg32,rm32,simm32_32 is vexMode=0 & opsize=1 & byte=0x69; (rm32 & Reg32 ... & check_Reg32_dest ...) ; simm32_32 { tmp:8 = sext(rm32) * sext(simm32_32); Reg32 = tmp(0); high:4 = tmp(4); imultflags(Reg32,tmp); build check_Reg32_dest; } @ifdef IA64 -:IMUL Reg64,rm64,simm32_32 is vexMode=0 & opsize=2 & byte=0x69; (rm64 & Reg64 ...) ; simm32_32 { tmp:16 = sext(rm64) * sext(simm32_32); +:IMUL Reg64,rm64,simm32_32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x69; (rm64 & Reg64 ...) ; simm32_32 { tmp:16 = sext(rm64) * sext(simm32_32); Reg64 = rm64 * sext(simm32_32); high:8 = tmp(8); imultflags(Reg64,tmp);} @endif @@ -2747,26 +2754,24 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } :IN AX, imm8 is vexMode=0 & opsize=0 & AX & (byte=0xe5; imm8) { tmp:1 = imm8; AX = in(tmp); } :IN EAX, imm8 is vexMode=0 & opsize=1 & EAX & check_EAX_dest & (byte=0xe5; imm8) { tmp:1 = imm8; EAX = in(tmp); build check_EAX_dest; } @ifdef IA64 -:IN RAX, imm8 is vexMode=0 & opsize=2 & RAX & (byte=0xe5; imm8) { tmp:1 = imm8; RAX = in(tmp); } +:IN RAX, imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & RAX & (byte=0xe5; imm8) { tmp:1 = imm8; RAX = in(tmp); } @endif :IN AL, DX is vexMode=0 & AL & DX & (byte=0xec) { AL = in(DX); } :IN AX, DX is vexMode=0 & opsize=0 & AX & DX & (byte=0xed) { AX = in(DX); } :IN EAX, DX is vexMode=0 & opsize=1 & EAX & check_EAX_dest & DX & (byte=0xed) { EAX = in(DX); build check_EAX_dest; } @ifdef IA64 -:IN RAX, DX is vexMode=0 & opsize=2 & RAX & DX & (byte=0xed) { RAX = in(DX); } +:IN RAX, DX is $(LONGMODE_ON) & vexMode=0 & opsize=2 & RAX & DX & (byte=0xed) { RAX = in(DX); } @endif :INC spec_rm8 is vexMode=0 & byte=0xfe; spec_rm8 & reg_opcode=0 ... { OF = scarry(spec_rm8,1); spec_rm8 = spec_rm8 + 1; resultflags( spec_rm8); } :INC spec_rm16 is vexMode=0 & opsize=0 & byte=0xff; spec_rm16 & reg_opcode=0 ... { OF = scarry(spec_rm16,1); spec_rm16 = spec_rm16 + 1; resultflags(spec_rm16); } :INC spec_rm32 is vexMode=0 & opsize=1 & byte=0xff; spec_rm32 & check_rm32_dest ... & reg_opcode=0 ... { OF = scarry(spec_rm32,1); spec_rm32 = spec_rm32 + 1; build check_rm32_dest; resultflags(spec_rm32); } @ifdef IA64 -:INC spec_rm64 is vexMode=0 & opsize=2 & byte=0xff; spec_rm64 & reg_opcode=0 ... { OF = scarry(spec_rm64,1); spec_rm64 = spec_rm64 + 1; resultflags(spec_rm64); } +:INC spec_rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xff; spec_rm64 & reg_opcode=0 ... { OF = scarry(spec_rm64,1); spec_rm64 = spec_rm64 + 1; resultflags(spec_rm64); } @endif -@ifndef IA64 -:INC Rmr16 is vexMode=0 & opsize=0 & row = 4 & page = 0 & Rmr16 { OF = scarry(Rmr16,1); Rmr16 = Rmr16 + 1; resultflags( Rmr16); } -:INC Rmr32 is vexMode=0 & opsize=1 & row = 4 & page = 0 & Rmr32 { OF = scarry(Rmr32,1); Rmr32 = Rmr32 + 1; resultflags( Rmr32); } -@endif +:INC Rmr16 is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & row = 4 & page = 0 & Rmr16 { OF = scarry(Rmr16,1); Rmr16 = Rmr16 + 1; resultflags( Rmr16); } +:INC Rmr32 is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & row = 4 & page = 0 & Rmr32 { OF = scarry(Rmr32,1); Rmr32 = Rmr32 + 1; resultflags( Rmr32); } :INSB^rep^reptail eseDI1,DX is vexMode=0 & rep & reptail & byte=0x6c & eseDI1 & DX { build rep; build eseDI1; eseDI1 = in(DX); build reptail; } :INSW^rep^reptail eseDI2,DX is vexMode=0 & rep & reptail & opsize=0 & byte=0x6d & eseDI2 & DX { build rep; build eseDI2; eseDI2 = in(DX); build reptail; } @@ -2792,24 +2797,24 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } :INVLPGA is vexMode=0 & addrsize=0 & byte=0xf; byte=0x1; byte=0xDF { invlpga(AX,ECX); } :INVLPGA is vexMode=0 & addrsize=1 & byte=0xf; byte=0x1; byte=0xDF { invlpga(EAX,ECX); } @ifdef IA64 -:INVLPGA is vexMode=0 & addrsize=2 & byte=0xf; byte=0x1; byte=0xDF { invlpga(RAX,ECX); } +:INVLPGA is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xf; byte=0x1; byte=0xDF { invlpga(RAX,ECX); } @endif :INVPCID r32, m128 is vexMode=0 & addrsize=1 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x82; r32 ... & m128 { invpcid(r32, m128); } @ifdef IA64 -:INVPCID r64, m128 is vexMode=0 & addrsize=2 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x82; r64 ... & m128 { invpcid(r64, m128); } +:INVPCID r64, m128 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x82; r64 ... & m128 { invpcid(r64, m128); } @endif :IRET is vexMode=0 & addrsize=0 & opsize=0 & byte=0xcf { pop22(IP); EIP=zext(IP); pop22(CS); pop22(flags); return [EIP]; } :IRET is vexMode=0 & addrsize=1 & opsize=0 & byte=0xcf { pop42(IP); EIP=zext(IP); pop42(CS); pop42(flags); return [EIP]; } @ifdef IA64 -:IRET is vexMode=0 & addrsize=2 & opsize=0 & byte=0xcf { pop82(IP); RIP=zext(IP); pop82(CS); pop82(flags); return [RIP]; } +:IRET is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xcf { pop82(IP); RIP=zext(IP); pop82(CS); pop82(flags); return [RIP]; } @endif :IRETD is vexMode=0 & addrsize=0 & opsize=1 & byte=0xcf { pop24(EIP); tmp:4=0; pop24(tmp); CS=tmp(0); pop24(tmp); flags=tmp(0); return [EIP]; } :IRETD is vexMode=0 & addrsize=1 & opsize=1 & byte=0xcf { pop44(EIP); tmp:4=0; pop44(tmp); CS=tmp(0); pop44(eflags); return [EIP]; } @ifdef IA64 -:IRETD is vexMode=0 & addrsize=2 & opsize=1 & byte=0xcf { pop84(RIP); tmp:8=0; pop84(tmp); CS=tmp(0); pop84(eflags); return [RIP]; } -:IRETQ is vexMode=0 & addrsize=2 & opsize=2 & byte=0xcf { pop88(RIP); tmp:8=0; pop88(tmp); CS=tmp(0); pop88(eflags); return [RIP]; } +:IRETD is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0xcf { pop84(RIP); tmp:8=0; pop84(tmp); CS=tmp(0); pop84(eflags); return [RIP]; } +:IRETQ is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0xcf { pop88(RIP); tmp:8=0; pop88(tmp); CS=tmp(0); pop88(eflags); return [RIP]; } @endif :J^cc rel8 is vexMode=0 & row=7 & cc; rel8 { if (cc) goto rel8; } @@ -2818,13 +2823,13 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } :J^cc rel32 is vexMode=0 & opsize=2 & byte=0xf; row=8 & cc; rel32 { if (cc) goto rel32; } # The following is vexMode=0 & picked up by the line above. rel32 works for both 32 and 64 bit #@ifdef IA64 -#:J^cc rel32 is vexMode=0 & addrsize=2 & byte=0xf; row=8 & cc; rel32 { if (cc) goto rel32; } +#:J^cc rel32 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xf; row=8 & cc; rel32 { if (cc) goto rel32; } #@endif :JCXZ rel8 is vexMode=0 & opsize=0 & byte=0xe3; rel8 { if (CX==0) goto rel8; } :JECXZ rel8 is vexMode=0 & opsize=1 & byte=0xe3; rel8 { if (ECX==0) goto rel8; } @ifdef IA64 -:JRCXZ rel8 is vexMode=0 & opsize=2 & byte=0xe3; rel8 { if (RCX==0) goto rel8; } +:JRCXZ rel8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xe3; rel8 { if (RCX==0) goto rel8; } @endif :JMP rel8 is vexMode=0 & byte=0xeb; rel8 { goto rel8; } @@ -2835,7 +2840,7 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } :JMP rm16 is vexMode=0 & addrsize=1 & opsize=0 & byte=0xff; rm16 & reg_opcode=4 ... { goto [rm16]; } :JMP rm32 is vexMode=0 & addrsize=1 & opsize=1 & byte=0xff; rm32 & reg_opcode=4 ... { goto [rm32]; } @ifdef IA64 -:JMP rm64 is vexMode=0 & addrsize=2 & byte=0xff; rm64 & reg_opcode=4 ... { goto [rm64]; } +:JMP rm64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xff; rm64 & reg_opcode=4 ... { goto [rm64]; } @endif :JMPF ptr1616 is vexMode=0 & opsize=0 & byte=0xea; ptr1616 { goto ptr1616; } @@ -2859,45 +2864,39 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } :LAR Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x2; rm16 & Reg16 ... { Reg16 = rm16 & 0xff00; ZF=1; } :LAR Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x2; rm32 & Reg32 ... & check_Reg32_dest ... { Reg32 = rm32 & 0xffff00; build check_Reg32_dest; ZF=1; } @ifdef IA64 -:LAR Reg64,rm32 is vexMode=0 & opsize=2 & byte=0xf; byte=0x2; rm32 & Reg64 ... { Reg64 = zext( rm32 & 0xffff00 ); ZF=1; } +:LAR Reg64,rm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x2; rm32 & Reg64 ... { Reg64 = zext( rm32 & 0xffff00 ); ZF=1; } @endif :LDMXCSR m32 is vexMode=0 & byte=0xf; byte=0xae; ( mod != 0b11 & reg_opcode=2 ) ... & m32 { MXCSR = m32; } -@ifndef IA64 # 16 & 32-bit only -:LDS Reg16,Mem is vexMode=0 & opsize=0 & byte=0xC5; Mem & Reg16 ... { tmp:4 = *Mem; DS = tmp(2); Reg16 = tmp(0); } -:LDS Reg32,Mem is vexMode=0 & opsize=1 & byte=0xC5 & bit64=0; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; DS = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } -@endif +:LDS Reg16,Mem is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & byte=0xC5; Mem & Reg16 ... { tmp:4 = *Mem; DS = tmp(2); Reg16 = tmp(0); } +:LDS Reg32,Mem is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & byte=0xC5 & bit64=0; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; DS = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } :LSS Reg16,Mem is vexMode=0 & opsize=0 & byte=0x0F; byte=0xB2; Mem & Reg16 ... { tmp:4 = *Mem; SS = tmp(2); Reg16 = tmp(0); } :LSS Reg32,Mem is vexMode=0 & opsize=1 & byte=0x0F; byte=0xB2; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; SS = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } @ifdef IA64 -:LSS Reg64,Mem is vexMode=0 & opsize=2 & byte=0x0F; byte=0xB2; Mem & Reg64 ... { tmp:10 = *Mem; SS = tmp(8); Reg64 = tmp(0); } +:LSS Reg64,Mem is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0F; byte=0xB2; Mem & Reg64 ... { tmp:10 = *Mem; SS = tmp(8); Reg64 = tmp(0); } @endif -@ifndef IA64 # 16 & 32-bit only -:LES Reg16,Mem is vexMode=0 & opsize=0 & byte=0xC4; Mem & Reg16 ... { tmp:4 = *Mem; ES = tmp(2); Reg16 = tmp(0); } -:LES Reg32,Mem is vexMode=0 & opsize=1 & byte=0xC4 & bit64=0; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; ES = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } -@endif +:LES Reg16,Mem is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & byte=0xC4; Mem & Reg16 ... { tmp:4 = *Mem; ES = tmp(2); Reg16 = tmp(0); } +:LES Reg32,Mem is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & byte=0xC4 & bit64=0; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; ES = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } :LFS Reg16,Mem is vexMode=0 & opsize=0 & byte=0x0F; byte=0xB4; Mem & Reg16 ... { tmp:4 = *Mem; FS = tmp(2); Reg16 = tmp(0); } :LFS Reg32,Mem is vexMode=0 & opsize=1 & byte=0x0F; byte=0xB4; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; FS = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } @ifdef IA64 -:LFS Reg64,Mem is vexMode=0 & opsize=2 & byte=0x0F; byte=0xB4; Mem & Reg64 ... { tmp:10 = *Mem; FS = tmp(8); Reg64 = tmp(0); } +:LFS Reg64,Mem is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0F; byte=0xB4; Mem & Reg64 ... { tmp:10 = *Mem; FS = tmp(8); Reg64 = tmp(0); } @endif :LGS Reg16,Mem is vexMode=0 & opsize=0 & byte=0x0F; byte=0xB5; Mem & Reg16 ... { tmp:4 = *Mem; GS = tmp(2); Reg16 = tmp(0); } :LGS Reg32,Mem is vexMode=0 & opsize=1 & byte=0x0F; byte=0xB5; Mem & Reg32 ... & check_Reg32_dest ... { tmp:6 = *Mem; GS = tmp(4); Reg32 = tmp(0); build check_Reg32_dest; } @ifdef IA64 -:LGS Reg64,Mem is vexMode=0 & opsize=2 & byte=0x0F; byte=0xB5; Mem & Reg64 ... { tmp:10 = *Mem; GS = tmp(8); Reg64 = tmp(0); } +:LGS Reg64,Mem is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0F; byte=0xB5; Mem & Reg64 ... { tmp:10 = *Mem; GS = tmp(8); Reg64 = tmp(0); } @endif -@ifndef IA64 #in 64-bit mode address size of 16 is not encodable -:LEA Reg16,addr16 is vexMode=0 & opsize=0 & addrsize=0 & byte=0x8D; addr16 & Reg16 ... { Reg16 = addr16; } -:LEA Reg32,addr16 is vexMode=0 & opsize=1 & addrsize=0 & byte=0x8D; addr16 & Reg32 ... { Reg32 = zext(addr16); } -@endif +:LEA Reg16,addr16 is $(LONGMODE_OFF) & vexMode=0 & opsize=0 & addrsize=0 & byte=0x8D; addr16 & Reg16 ... { Reg16 = addr16; } +:LEA Reg32,addr16 is $(LONGMODE_OFF) & vexMode=0 & opsize=1 & addrsize=0 & byte=0x8D; addr16 & Reg32 ... { Reg32 = zext(addr16); } :LEA Reg16,addr32 is vexMode=0 & opsize=0 & addrsize=1 & byte=0x8D; addr32 & Reg16 ... { Reg16 = addr32(0); } :LEA Reg32,addr32 is vexMode=0 & opsize=1 & addrsize=1 & byte=0x8D; addr32 & Reg32 ... & check_Reg32_dest ... { @@ -2906,19 +2905,19 @@ enterFrames: low5 is low5 { tmp:1 = low5; export tmp; } } @ifdef IA64 -:LEA Reg16,addr64 is vexMode=0 & opsize=0 & addrsize=2 & byte=0x8D; addr64 & Reg16 ... { Reg16 = addr64(0); } -:LEA Reg32,addr64 is vexMode=0 & opsize=1 & addrsize=2 & byte=0x8D; addr64 & Reg32 ... & check_Reg32_dest ... { +:LEA Reg16,addr64 is $(LONGMODE_ON) & vexMode=0 & opsize=0 & addrsize=2 & byte=0x8D; addr64 & Reg16 ... { Reg16 = addr64(0); } +:LEA Reg32,addr64 is $(LONGMODE_ON) & vexMode=0 & opsize=1 & addrsize=2 & byte=0x8D; addr64 & Reg32 ... & check_Reg32_dest ... { Reg32 = addr64(0); build check_Reg32_dest; } -:LEA Reg64,addr32 is vexMode=0 & opsize=2 & addrsize=1 & byte=0x8D; addr32 & Reg64 ... { Reg64 = zext(addr32); } -:LEA Reg64,addr64 is vexMode=0 & opsize=2 & addrsize=2 & byte=0x8D; addr64 & Reg64 ... { Reg64 = addr64; } +:LEA Reg64,addr32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & addrsize=1 & byte=0x8D; addr32 & Reg64 ... { Reg64 = zext(addr32); } +:LEA Reg64,addr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & addrsize=2 & byte=0x8D; addr64 & Reg64 ... { Reg64 = addr64; } @endif :LEAVE is vexMode=0 & addrsize=0 & byte=0xc9 { SP = BP; tmp:$(SIZE) = segment(SS,SP); BP = *tmp; SP = SP + 2; } :LEAVE is vexMode=0 & addrsize=1 & byte=0xc9 { ESP = EBP; EBP = *$(STACKPTR); ESP=ESP+4; } @ifdef IA64 -:LEAVE is vexMode=0 & addrsize=2 & byte=0xc9 { RSP = RBP; RBP = *RSP; RSP=RSP+8; } +:LEAVE is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xc9 { RSP = RBP; RBP = *RSP; RSP=RSP+8; } @endif define pcodeop GlobalDescriptorTableRegister; @@ -2933,7 +2932,7 @@ define pcodeop GlobalDescriptorTableRegister; } @ifdef IA64 -:LGDT m64 is vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=2 ) ... & m64 +:LGDT m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=2 ) ... & m64 { GlobalDescriptorTableRegister(m64); } @@ -2950,7 +2949,7 @@ define pcodeop InterruptDescriptorTableRegister; InterruptDescriptorTableRegister(m32); } @ifdef IA64 -:LIDT m64 is vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=3 ) ... & m64 +:LIDT m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=3 ) ... & m64 { InterruptDescriptorTableRegister(m64); } @@ -2980,25 +2979,25 @@ define pcodeop LocalDescriptorTableRegister; :LODSW^rep^reptail dseSI2 is vexMode=0 & rep & reptail & opsize=0 & byte=0xAD & dseSI2 { build rep; build dseSI2; AX=dseSI2; build reptail; } :LODSD^rep^reptail dseSI4 is vexMode=0 & rep & reptail & opsize=1 & byte=0xAD & dseSI4 { build rep; build dseSI4; EAX=dseSI4; build reptail; } @ifdef IA64 -:LODSQ^rep^reptail dseSI8 is vexMode=0 & rep & reptail & opsize=2 & byte=0xAD & dseSI8 { build rep; build dseSI8; RAX=dseSI8; build reptail; } +:LODSQ^rep^reptail dseSI8 is $(LONGMODE_ON) & vexMode=0 & rep & reptail & opsize=2 & byte=0xAD & dseSI8 { build rep; build dseSI8; RAX=dseSI8; build reptail; } @endif :LOOP rel8 is vexMode=0 & addrsize=0 & byte=0xE2; rel8 { CX = CX -1; if (CX!=0) goto rel8; } :LOOP rel8 is vexMode=0 & addrsize=1 & byte=0xE2; rel8 { ECX = ECX -1; if (ECX!=0) goto rel8; } @ifdef IA64 -:LOOP rel8 is vexMode=0 & addrsize=2 & byte=0xE2; rel8 { RCX = RCX -1; if (RCX!=0) goto rel8; } +:LOOP rel8 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xE2; rel8 { RCX = RCX -1; if (RCX!=0) goto rel8; } @endif :LOOPZ rel8 is vexMode=0 & addrsize=0 & byte=0xE1; rel8 { CX = CX -1; if (CX!=0 && ZF!=0) goto rel8; } :LOOPZ rel8 is vexMode=0 & addrsize=1 & byte=0xE1; rel8 { ECX = ECX -1; if (ECX!=0 && ZF!=0) goto rel8; } @ifdef IA64 -:LOOPZ rel8 is vexMode=0 & addrsize=2 & byte=0xE1; rel8 { RCX = RCX -1; if (RCX!=0 && ZF!=0) goto rel8; } +:LOOPZ rel8 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xE1; rel8 { RCX = RCX -1; if (RCX!=0 && ZF!=0) goto rel8; } @endif :LOOPNZ rel8 is vexMode=0 & addrsize=0 & byte=0xE0; rel8 { CX = CX -1; if (CX!=0 && ZF==0) goto rel8; } :LOOPNZ rel8 is vexMode=0 & addrsize=1 & byte=0xE0; rel8 { ECX = ECX -1; if (ECX!=0 && ZF==0) goto rel8; } @ifdef IA64 -:LOOPNZ rel8 is vexMode=0 & addrsize=2 & byte=0xE0; rel8 { RCX = RCX -1; if (RCX!=0 && ZF==0) goto rel8; } +:LOOPNZ rel8 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xE0; rel8 { RCX = RCX -1; if (RCX!=0 && ZF==0) goto rel8; } @endif define pcodeop SegmentLimit; @@ -3017,7 +3016,7 @@ define pcodeop SegmentLimit; } @ifdef IA64 -:LSL Reg64,rm32 is vexMode=0 & opsize=2 & byte=0xf; byte=0x3; rm32 & Reg64 ... +:LSL Reg64,rm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x3; rm32 & Reg64 ... { tmp:3 = SegmentLimit(rm32); Reg64 = zext(tmp:2); @@ -3033,14 +3032,14 @@ define pcodeop TaskRegister; #:MOV rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x89; rm32 & Reg32 ... { rm32=Reg32; } :MOV rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x89; rm32 & check_rm32_dest ... & Reg32 ... { rm32=Reg32; build check_rm32_dest; } @ifdef IA64 -:MOV rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x89; rm64 & Reg64 ... { rm64=Reg64; } +:MOV rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x89; rm64 & Reg64 ... { rm64=Reg64; } @endif :MOV Reg8,rm8 is vexMode=0 & byte=0x8a; rm8 & Reg8 ... { Reg8 = rm8; } :MOV Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x8b; rm16 & Reg16 ... { Reg16 = rm16; } #:MOV Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x8b; rm32 & Reg32 ... { Reg32 = rm32; } :MOV Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x8b; rm32 & Reg32 ... & check_Reg32_dest ... { Reg32 = rm32; build check_Reg32_dest; } @ifdef IA64 -:MOV Reg64,rm64 is vexMode=0 & opsize=2 & byte=0x8b; rm64 & Reg64 ... { Reg64 = rm64; } +:MOV Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x8b; rm64 & Reg64 ... { Reg64 = rm64; } @endif :MOV rm16,Sreg is vexMode=0 & byte=0x8c; rm16 & Sreg ... { rm16 = Sreg; } :MOV Sreg,rm16 is vexMode=0 & byte=0x8e; rm16 & Sreg ... { Sreg=rm16; } @@ -3048,19 +3047,19 @@ define pcodeop TaskRegister; :MOV AX,moffs16 is vexMode=0 & opsize=0 & byte=0xa1; AX & moffs16 { AX=moffs16; } :MOV EAX,moffs32 is vexMode=0 & opsize=1 & byte=0xa1; EAX & check_EAX_dest & moffs32 { EAX=moffs32; build check_EAX_dest; } @ifdef IA64 -:MOV RAX,moffs64 is vexMode=0 & opsize=2 & byte=0xa1; RAX & moffs64 { RAX=moffs64; } +:MOV RAX,moffs64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xa1; RAX & moffs64 { RAX=moffs64; } @endif :MOV moffs8,AL is vexMode=0 & byte=0xa2; AL & moffs8 { moffs8=AL; } :MOV moffs16,AX is vexMode=0 & opsize=0 & byte=0xa3; AX & moffs16 { moffs16=AX; } :MOV moffs32,EAX is vexMode=0 & opsize=1 & byte=0xa3; EAX & moffs32 { moffs32=EAX; } @ifdef IA64 -:MOV moffs64,RAX is vexMode=0 & opsize=2 & byte=0xa3; RAX & moffs64 { moffs64=RAX; } +:MOV moffs64,RAX is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xa3; RAX & moffs64 { moffs64=RAX; } @endif :MOV CRmr8,imm8 is vexMode=0 & row=11 & page=0 & CRmr8; imm8 { CRmr8 = imm8; } :MOV CRmr16,imm16 is vexMode=0 & opsize=0 & row=11 & page=1 & CRmr16; imm16 { CRmr16 = imm16; } :MOV CRmr32,imm32 is vexMode=0 & opsize=1 & row=11 & page=1 & CRmr32; imm32 { CRmr32 = imm32; } @ifdef IA64 -:MOV Rmr64,imm64 is vexMode=0 & opsize=2 & row=11 & page=1 & Rmr64; imm64 { Rmr64 = imm64; } +:MOV Rmr64,imm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & row=11 & page=1 & Rmr64; imm64 { Rmr64 = imm64; } @endif :MOV spec_rm8,imm8 is vexMode=0 & byte=0xc6; (spec_rm8 & reg_opcode=0 ...); imm8 { spec_rm8 = imm8; } :MOV CRmr8,imm8 is vexMode=0 & byte=0xc6; (CRmr8 & mod=3 & reg_opcode=0); imm8 { CRmr8 = imm8; } @@ -3068,7 +3067,7 @@ define pcodeop TaskRegister; :MOV CRmr16,imm16 is vexMode=0 & opsize=0 & byte=0xc7; (CRmr16 & mod=3 & reg_opcode=0); imm16 { CRmr16 = imm16; } :MOV spec_rm32,imm32 is vexMode=0 & opsize=1 & byte=0xc7; (spec_rm32 & check_rm32_dest ... & reg_opcode=0 ...); imm32 { spec_rm32 = imm32; build check_rm32_dest; } @ifdef IA64 -:MOV spec_rm64,simm32 is vexMode=0 & opsize=2 & byte=0xc7; (spec_rm64 & reg_opcode=0 ...); simm32 { spec_rm64 = simm32; } +:MOV spec_rm64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xc7; (spec_rm64 & reg_opcode=0 ...); simm32 { spec_rm64 = simm32; } @endif :MOV creg, Rmr32 is vexMode=0 & byte=0xf; byte=0x22; Rmr32 & creg { @ifdef IA64 @@ -3079,8 +3078,8 @@ define pcodeop TaskRegister; } @ifdef IA64 :MOV creg_x, Rmr32 is vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x22; Rmr32 & creg_x { creg_x=zext(Rmr32); } -:MOV creg, Rmr64 is vexMode=0 & bit64=1 & byte=0xf; byte=0x22; Rmr64 & creg { creg=Rmr64; } -:MOV creg_x, Rmr64 is vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x22; Rmr64 & creg_x { creg_x=Rmr64; } +:MOV creg, Rmr64 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & byte=0xf; byte=0x22; Rmr64 & creg { creg=Rmr64; } +:MOV creg_x, Rmr64 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x22; Rmr64 & creg_x { creg_x=Rmr64; } @endif :MOV Rmr32, creg is vexMode=0 & byte=0xf; byte=0x20; Rmr32 & creg { @ifdef IA64 @@ -3091,8 +3090,8 @@ define pcodeop TaskRegister; } :MOV Rmr32, creg_x is vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x20; Rmr32 & creg_x { Rmr32 = creg_x:4; } @ifdef IA64 -:MOV Rmr64, creg is vexMode=0 & bit64=1 & byte=0xf; byte=0x20; Rmr64 & creg { Rmr64 = creg; } -:MOV Rmr64, creg_x is vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x20; Rmr64 & creg_x { Rmr64 = creg_x; } +:MOV Rmr64, creg is $(LONGMODE_ON) & vexMode=0 & bit64=1 & byte=0xf; byte=0x20; Rmr64 & creg { Rmr64 = creg; } +:MOV Rmr64, creg_x is $(LONGMODE_ON) & vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x20; Rmr64 & creg_x { Rmr64 = creg_x; } @endif :MOV Rmr32, debugreg is vexMode=0 & byte=0xf; byte=0x21; Rmr32 & debugreg { @ifdef IA64 @@ -3103,8 +3102,8 @@ define pcodeop TaskRegister; } :MOV Rmr32, debugreg_x is vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x21; Rmr32 & debugreg_x { Rmr32 = debugreg_x:4; } @ifdef IA64 -:MOV Rmr64, debugreg is vexMode=0 & bit64=1 & byte=0xf; byte=0x21; Rmr64 & debugreg { Rmr64 = debugreg; } -:MOV Rmr64, debugreg_x is vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x21; Rmr64 & debugreg_x { Rmr64 = debugreg_x; } +:MOV Rmr64, debugreg is $(LONGMODE_ON) & vexMode=0 & bit64=1 & byte=0xf; byte=0x21; Rmr64 & debugreg { Rmr64 = debugreg; } +:MOV Rmr64, debugreg_x is $(LONGMODE_ON) & vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x21; Rmr64 & debugreg_x { Rmr64 = debugreg_x; } @endif :MOV debugreg, Rmr32 is vexMode=0 & byte=0xf; byte=0x23; Rmr32 & debugreg { @ifdef IA64 @@ -3115,8 +3114,8 @@ define pcodeop TaskRegister; } @ifdef IA64 :MOV debugreg_x, Rmr32 is vexMode=0 & rexRprefix=1 & byte=0xf; byte=0x23; Rmr32 & debugreg_x & mod=3 { debugreg_x = zext(Rmr32); } -:MOV debugreg, Rmr64 is vexMode=0 & bit64=1 & byte=0xf; byte=0x23; Rmr64 & debugreg & mod=3 { debugreg = Rmr64; } -:MOV debugreg_x, Rmr64 is vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x23; Rmr64 & debugreg_x & mod=3 { debugreg_x = Rmr64; } +:MOV debugreg, Rmr64 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & byte=0xf; byte=0x23; Rmr64 & debugreg & mod=3 { debugreg = Rmr64; } +:MOV debugreg_x, Rmr64 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & rexRprefix=1 & byte=0xf; byte=0x23; Rmr64 & debugreg_x & mod=3 { debugreg_x = Rmr64; } @endif @ifndef IA64 @@ -3133,54 +3132,54 @@ define pcodeop swap_bytes; :MOVBE m16, Reg16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x38; byte=0xf1; Reg16 ... & m16 { m16 = swap_bytes( Reg16 ); } :MOVBE m32, Reg32 is vexMode=0 & opsize=1 & mandover=0 & byte=0xf; byte=0x38; byte=0xf1; Reg32 ... & m32 { m32 = swap_bytes( Reg32 ); } @ifdef IA64 -:MOVBE Reg64, m64 is vexMode=0 & opsize=2 & mandover=0 & byte=0xf; byte=0x38; byte=0xf0; Reg64 ... & m64 { Reg64 = swap_bytes( m64 ); } -:MOVBE m64, Reg64 is vexMode=0 & opsize=2 & mandover=0 & byte=0xf; byte=0x38; byte=0xf1; Reg64 ... & m64 { m64 = swap_bytes( Reg64 ); } +:MOVBE Reg64, m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0xf; byte=0x38; byte=0xf0; Reg64 ... & m64 { Reg64 = swap_bytes( m64 ); } +:MOVBE m64, Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0xf; byte=0x38; byte=0xf1; Reg64 ... & m64 { m64 = swap_bytes( Reg64 ); } @endif :MOVNTI Mem,Reg32 is vexMode=0 & opsize = 1; byte=0xf; byte=0xc3; Mem & Reg32 ... { *Mem = Reg32; } @ifdef IA64 -:MOVNTI Mem,Reg64 is vexMode=0 & opsize = 2; byte=0xf; byte=0xc3; Mem & Reg64 ... { *Mem = Reg64; } +:MOVNTI Mem,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize = 2; byte=0xf; byte=0xc3; Mem & Reg64 ... { *Mem = Reg64; } @endif :MOVSB^rep^reptail eseDI1,dseSI1 is vexMode=0 & rep & reptail & byte=0xa4 & eseDI1 & dseSI1 { build rep; build eseDI1; build dseSI1; eseDI1 = dseSI1; build reptail; } :MOVSW^rep^reptail eseDI2,dseSI2 is vexMode=0 & rep & reptail & opsize=0 & byte=0xa5 & eseDI2 & dseSI2 { build rep; build eseDI2; build dseSI2; eseDI2 = dseSI2; build reptail; } :MOVSD^rep^reptail eseDI4,dseSI4 is vexMode=0 & rep & reptail & opsize=1 & byte=0xa5 & eseDI4 & dseSI4 { build rep; build eseDI4; build dseSI4; eseDI4 = dseSI4; build reptail; } @ifdef IA64 -:MOVSQ^rep^reptail eseDI8,dseSI8 is vexMode=0 & rep & reptail & opsize=2 & byte=0xa5 & eseDI8 & dseSI8 { build rep; build eseDI8; build dseSI8; eseDI8 = dseSI8; build reptail; } +:MOVSQ^rep^reptail eseDI8,dseSI8 is $(LONGMODE_ON) & vexMode=0 & rep & reptail & opsize=2 & byte=0xa5 & eseDI8 & dseSI8 { build rep; build eseDI8; build dseSI8; eseDI8 = dseSI8; build reptail; } @endif :MOVSX Reg16,spec_rm8 is vexMode=0 & opsize=0 & byte=0xf; byte=0xbe; spec_rm8 & Reg16 ... { Reg16 = sext(spec_rm8); } :MOVSX Reg32,spec_rm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xbe; spec_rm8 & Reg32 ... & check_Reg32_dest ... { Reg32 = sext(spec_rm8); build check_Reg32_dest; } @ifdef IA64 -:MOVSX Reg64,spec_rm8 is vexMode=0 & opsize=2 & byte=0xf; byte=0xbe; spec_rm8 & Reg64 ... { Reg64 = sext(spec_rm8); } +:MOVSX Reg64,spec_rm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xbe; spec_rm8 & Reg64 ... { Reg64 = sext(spec_rm8); } @endif :MOVSX Reg32,spec_rm16 is vexMode=0 & byte=0xf; byte=0xbf; spec_rm16 & Reg32 ... & check_Reg32_dest ... { Reg32 = sext(spec_rm16); build check_Reg32_dest; } @ifdef IA64 -:MOVSX Reg64,spec_rm16 is vexMode=0 & opsize=2 & byte=0xf; byte=0xbf; spec_rm16 & Reg64 ... { Reg64 = sext(spec_rm16); } +:MOVSX Reg64,spec_rm16 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xbf; spec_rm16 & Reg64 ... { Reg64 = sext(spec_rm16); } @endif :MOVSXD Reg32,rm32 is vexMode=0 & bit64=1 & opsize=1 & byte=0x63; rm32 & Reg32 ... & check_Reg32_dest ... { Reg32 = rm32; build check_Reg32_dest; } @ifdef IA64 -:MOVSXD Reg64,rm32 is vexMode=0 & bit64=1 & opsize=2 & byte=0x63; rm32 & Reg64 ... { Reg64 = sext(rm32); } +:MOVSXD Reg64,rm32 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & opsize=2 & byte=0x63; rm32 & Reg64 ... { Reg64 = sext(rm32); } @endif :MOVZX Reg16,spec_rm8 is vexMode=0 & opsize=0 & byte=0xf; byte=0xb6; spec_rm8 & Reg16 ... { Reg16 = zext(spec_rm8); } :MOVZX Reg32,spec_rm8 is vexMode=0 & opsize=1 & byte=0xf; byte=0xb6; spec_rm8 & Reg32 ... & check_Reg32_dest ... { Reg32 = zext(spec_rm8); build check_Reg32_dest; } @ifdef IA64 -:MOVZX Reg64,spec_rm8 is vexMode=0 & opsize=2 & byte=0xf; byte=0xb6; spec_rm8 & Reg64 ... { Reg64 = zext(spec_rm8); } +:MOVZX Reg64,spec_rm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xb6; spec_rm8 & Reg64 ... { Reg64 = zext(spec_rm8); } @endif :MOVZX Reg32,spec_rm16 is vexMode=0 & byte=0xf; byte=0xb7; spec_rm16 & Reg32 ... & check_Reg32_dest ... { Reg32 = zext(spec_rm16); build check_Reg32_dest; } @ifdef IA64 -:MOVZX Reg64,spec_rm16 is vexMode=0 & opsize=2 & byte=0xf; byte=0xb7; spec_rm16 & Reg64 ... { Reg64 = zext(spec_rm16); } +:MOVZX Reg64,spec_rm16 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0xb7; spec_rm16 & Reg64 ... { Reg64 = zext(spec_rm16); } @endif :MUL rm8 is vexMode=0 & byte=0xf6; rm8 & reg_opcode=4 ... { AX=zext(AL)*zext(rm8); multflags(AH); } :MUL rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=4 ... { tmp:4=zext(AX)*zext(rm16); DX=tmp(2); AX=tmp(0); multflags(DX); } :MUL rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_EAX_dest ... & check_EDX_dest ... & reg_opcode=4 ... { tmp:8=zext(EAX)*zext(rm32); EDX=tmp(4); build check_EDX_dest; multflags(EDX); EAX=tmp(0); build check_EAX_dest; } @ifdef IA64 -:MUL rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=4 ... { tmp:16=zext(RAX)*zext(rm64); RDX=tmp(8); RAX=tmp(0); multflags(RDX); } +:MUL rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=4 ... { tmp:16=zext(RAX)*zext(rm64); RDX=tmp(8); RAX=tmp(0); multflags(RDX); } @endif :MWAIT is vexMode=0 & byte=0x0f; byte=0x01; byte=0xC9 { mwait(); } @@ -3192,7 +3191,7 @@ define pcodeop swap_bytes; :NEG rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=3 ... { negflags(rm16); rm16 = -rm16; resultflags(rm16); } :NEG rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_rm32_dest ... & reg_opcode=3 ... { negflags(rm32); rm32 = -rm32; resultflags(rm32); build check_rm32_dest;} @ifdef IA64 -:NEG rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=3 ... { negflags(rm64); rm64 = -rm64; resultflags(rm64); } +:NEG rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=3 ... { negflags(rm64); rm64 = -rm64; resultflags(rm64); } @endif :NOP is vexMode=0 & opsize=0 & byte=0x90 { } @@ -3208,37 +3207,37 @@ define pcodeop swap_bytes; :NOT rm16 is vexMode=0 & opsize=0 & byte=0xf7; rm16 & reg_opcode=2 ... { rm16 = ~rm16; } :NOT rm32 is vexMode=0 & opsize=1 & byte=0xf7; rm32 & check_rm32_dest ... & reg_opcode=2 ... { rm32 = ~rm32; build check_rm32_dest;} @ifdef IA64 -:NOT rm64 is vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=2 ... { rm64 = ~rm64; } +:NOT rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf7; rm64 & reg_opcode=2 ... { rm64 = ~rm64; } @endif :OR AL,imm8 is vexMode=0 & byte=0x0c; AL & imm8 { logicalflags(); AL = AL | imm8; resultflags( AL); } :OR AX,imm16 is vexMode=0 & opsize=0 & byte=0xd; AX & imm16 { logicalflags(); AX = AX | imm16; resultflags( AX); } :OR EAX,imm32 is vexMode=0 & opsize=1 & byte=0xd; EAX & check_EAX_dest & imm32 { logicalflags(); EAX = EAX | imm32; build check_EAX_dest; resultflags( EAX); } @ifdef IA64 -:OR RAX,simm32 is vexMode=0 & opsize=2 & byte=0xd; RAX & simm32 { logicalflags(); RAX = RAX | simm32; resultflags( RAX); } +:OR RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xd; RAX & simm32 { logicalflags(); RAX = RAX | simm32; resultflags( RAX); } @endif :OR spec_rm8,imm8 is vexMode=0 & (byte=0x80 | byte=0x82); spec_rm8 & reg_opcode=1 ...; imm8 { logicalflags(); spec_rm8 = spec_rm8 | imm8; resultflags( spec_rm8); } :OR spec_rm16,imm16 is vexMode=0 & opsize=0 & byte=0x81; spec_rm16 & reg_opcode=1 ...; imm16 { logicalflags(); spec_rm16 = spec_rm16 | imm16; resultflags( spec_rm16); } :OR spec_rm32,imm32 is vexMode=0 & opsize=1 & byte=0x81; spec_rm32 & check_rm32_dest ... & reg_opcode=1 ...; imm32 { logicalflags(); spec_rm32 = spec_rm32 | imm32; build check_rm32_dest; resultflags( spec_rm32); } @ifdef IA64 -:OR spec_rm64,simm32 is vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=1 ...; simm32 { logicalflags(); tmp:8 = spec_rm64; spec_rm64 = tmp | simm32; resultflags( spec_rm64); } +:OR spec_rm64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=1 ...; simm32 { logicalflags(); tmp:8 = spec_rm64; spec_rm64 = tmp | simm32; resultflags( spec_rm64); } @endif :OR spec_rm16,usimm8_16 is vexMode=0 & opsize=0 & byte=0x83; spec_rm16 & reg_opcode=1 ...; usimm8_16 { logicalflags(); spec_rm16 = spec_rm16 | usimm8_16; resultflags( spec_rm16); } :OR spec_rm32,usimm8_32 is vexMode=0 & opsize=1 & byte=0x83; spec_rm32 & check_rm32_dest ... & reg_opcode=1 ...; usimm8_32 { logicalflags(); spec_rm32 = spec_rm32 | usimm8_32; build check_rm32_dest; resultflags( spec_rm32); } @ifdef IA64 -:OR spec_rm64,usimm8_64 is vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=1 ...; usimm8_64 { logicalflags(); spec_rm64 = spec_rm64 | usimm8_64; resultflags( spec_rm64); } +:OR spec_rm64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=1 ...; usimm8_64 { logicalflags(); spec_rm64 = spec_rm64 | usimm8_64; resultflags( spec_rm64); } @endif :OR rm8,Reg8 is vexMode=0 & byte=0x8; rm8 & Reg8 ... { logicalflags(); rm8 = rm8 | Reg8; resultflags( rm8); } :OR rm16,Reg16 is vexMode=0 & opsize=0 & byte=0x9; rm16 & Reg16 ... { logicalflags(); rm16 = rm16 | Reg16; resultflags( rm16); } :OR rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x9; rm32 & check_rm32_dest ... & Reg32 ... { logicalflags(); rm32 = rm32 | Reg32; build check_rm32_dest; resultflags( rm32); } @ifdef IA64 -:OR rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x9; rm64 & Reg64 ... { logicalflags(); rm64 = rm64 | Reg64; resultflags( rm64); } +:OR rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x9; rm64 & Reg64 ... { logicalflags(); rm64 = rm64 | Reg64; resultflags( rm64); } @endif :OR Reg8,rm8 is vexMode=0 & byte=0xa; rm8 & Reg8 ... { logicalflags(); Reg8 = Reg8 | rm8; resultflags( Reg8); } :OR Reg16,rm16 is vexMode=0 & opsize=0 & byte=0xb; rm16 & Reg16 ... { logicalflags(); Reg16 = Reg16 | rm16; resultflags(Reg16); } :OR Reg32,rm32 is vexMode=0 & opsize=1 & byte=0xb; rm32 & Reg32 ... & check_Reg32_dest ... { logicalflags(); Reg32 = Reg32 | rm32; build check_Reg32_dest; resultflags(Reg32); } @ifdef IA64 -:OR Reg64,rm64 is vexMode=0 & opsize=2 & byte=0xb; rm64 & Reg64 ... { logicalflags(); Reg64 = Reg64 | rm64; resultflags(Reg64); } +:OR Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xb; rm64 & Reg64 ... { logicalflags(); Reg64 = Reg64 | rm64; resultflags(Reg64); } @endif :OUT imm8,AL is vexMode=0 & byte=0xe6; imm8 & AL { tmp:1 = imm8; out(tmp,AL); } @@ -3260,8 +3259,8 @@ define pcodeop swap_bytes; :POP rm32 is vexMode=0 & addrsize=0 & opsize=1 & byte=0x8f; rm32 & reg_opcode=0 ... { pop24(rm32); } :POP rm32 is vexMode=0 & addrsize=1 & opsize=1 & byte=0x8f; rm32 & reg_opcode=0 ... { pop44(rm32); } @ifdef IA64 -:POP rm16 is vexMode=0 & addrsize=2 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { pop82(rm16); } -:POP rm64 is vexMode=0 & addrsize=2 & byte=0x8f; rm64 & reg_opcode=0 ... { pop88(rm64); } +:POP rm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x8f; rm16 & reg_opcode=0 ... { pop82(rm16); } +:POP rm64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x8f; rm64 & reg_opcode=0 ... { pop88(rm64); } @endif :POP Rmr16 is vexMode=0 & addrsize=0 & opsize=0 & row=5 & page=1 & Rmr16 { pop22(Rmr16); } @@ -3269,8 +3268,8 @@ define pcodeop swap_bytes; :POP Rmr32 is vexMode=0 & addrsize=0 & opsize=1 & row=5 & page=1 & Rmr32 { pop24(Rmr32); } :POP Rmr32 is vexMode=0 & addrsize=1 & opsize=1 & row=5 & page=1 & Rmr32 { pop44(Rmr32); } @ifdef IA64 -:POP Rmr16 is vexMode=0 & addrsize=2 & opsize=0 & row=5 & page=1 & Rmr16 { pop82(Rmr16); } -:POP Rmr64 is vexMode=0 & addrsize=2 & row=5 & page=1 & Rmr64 { pop88(Rmr64); } +:POP Rmr16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & row=5 & page=1 & Rmr16 { pop82(Rmr16); } +:POP Rmr64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & row=5 & page=1 & Rmr64 { pop88(Rmr64); } @endif :POP DS is vexMode=0 & addrsize=0 & byte=0x1f & DS { pop22(DS); } @@ -3282,12 +3281,12 @@ define pcodeop swap_bytes; :POP FS is vexMode=0 & addrsize=0 & byte=0xf; byte=0xa1 & FS { pop22(FS); } :POP FS is vexMode=0 & addrsize=1 & byte=0xf; byte=0xa1 & FS { popseg44(FS); } @ifdef IA64 -:POP FS is vexMode=0 & addrsize=2 & byte=0xf; byte=0xa1 & FS { popseg88(FS); } +:POP FS is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xf; byte=0xa1 & FS { popseg88(FS); } @endif :POP GS is vexMode=0 & addrsize=0 & byte=0xf; byte=0xa9 & GS { pop22(GS); } :POP GS is vexMode=0 & addrsize=1 & byte=0xf; byte=0xa9 & GS { popseg44(GS); } @ifdef IA64 -:POP GS is vexMode=0 & addrsize=2 & byte=0xf; byte=0xa9 & GS { popseg88(GS); } +:POP GS is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xf; byte=0xa9 & GS { popseg88(GS); } @endif :POPA is vexMode=0 & addrsize=0 & opsize=0 & byte=0x61 { pop22(DI); pop22(SI); pop22(BP); tmp:2=0; pop22(tmp); pop22(BX); pop22(DX); pop22(CX); pop22(AX); } @@ -3299,9 +3298,9 @@ define pcodeop swap_bytes; :POPFD is vexMode=0 & addrsize=0 & opsize=1 & byte=0x9d { pop24(eflags); unpackflags(eflags); unpackeflags(eflags); } :POPFD is vexMode=0 & addrsize=1 & opsize=1 & byte=0x9d { pop44(eflags); unpackflags(eflags); unpackeflags(eflags); } @ifdef IA64 -:POPF is vexMode=0 & addrsize=2 & opsize=0 & byte=0x9d { pop82(flags); unpackflags(flags); } -:POPFD is vexMode=0 & addrsize=2 & opsize=1 & byte=0x9d { pop84(eflags); unpackflags(eflags); unpackeflags(eflags); } -:POPFQ is vexMode=0 & addrsize=2 & opsize=2 & byte=0x9d { pop88(rflags); unpackflags(rflags); unpackeflags(rflags); } +:POPF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x9d { pop82(flags); unpackflags(flags); } +:POPFD is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0x9d { pop84(eflags); unpackflags(eflags); unpackeflags(eflags); } +:POPFQ is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0x9d { pop88(rflags); unpackflags(rflags); unpackeflags(rflags); } @endif :PREFETCH m8 is vexMode=0 & byte=0x0f; byte=0x0d; m8 & reg_opcode=0 ... { } @@ -3323,38 +3322,38 @@ define pcodeop ptwrite; :PUSH rm32 is vexMode=0 & addrsize=0 & opsize=1 & byte=0xff; rm32 & reg_opcode=6 ... { push24(rm32); } :PUSH rm32 is vexMode=0 & addrsize=1 & opsize=1 & byte=0xff; rm32 & reg_opcode=6 ... { push44(rm32); } @ifdef IA64 -:PUSH rm16 is vexMode=0 & addrsize=2 & opsize=0 & byte=0xff; rm16 & reg_opcode=6 ... { push82(rm16); } -:PUSH rm64 is vexMode=0 & addrsize=2 & byte=0xff; rm64 & reg_opcode=6 ... { push88(rm64); } +:PUSH rm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xff; rm16 & reg_opcode=6 ... { push82(rm16); } +:PUSH rm64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xff; rm64 & reg_opcode=6 ... { push88(rm64); } @endif :PUSH Rmr16 is vexMode=0 & addrsize=0 & opsize=0 & row=5 & page=0 & Rmr16 { push22(Rmr16); } :PUSH Rmr16 is vexMode=0 & addrsize=1 & opsize=0 & row=5 & page=0 & Rmr16 { push42(Rmr16); } :PUSH Rmr32 is vexMode=0 & addrsize=0 & opsize=1 & row=5 & page=0 & Rmr32 { push24(Rmr32); } :PUSH Rmr32 is vexMode=0 & addrsize=1 & opsize=1 & row=5 & page=0 & Rmr32 { push44(Rmr32); } @ifdef IA64 -:PUSH Rmr16 is vexMode=0 & addrsize=2 & opsize=0 & row=5 & page=0 & Rmr16 { push82(Rmr16); } -:PUSH Rmr64 is vexMode=0 & addrsize=2 & row=5 & page=0 & Rmr64 { push88(Rmr64); } +:PUSH Rmr16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & row=5 & page=0 & Rmr16 { push82(Rmr16); } +:PUSH Rmr64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & row=5 & page=0 & Rmr64 { push88(Rmr64); } @endif :PUSH simm8_16 is vexMode=0 & addrsize=0 & opsize=0 & byte=0x6a; simm8_16 { tmp:2=simm8_16; push22(tmp); } :PUSH simm8_16 is vexMode=0 & addrsize=1 & opsize=0 & byte=0x6a; simm8_16 { tmp:2=simm8_16; push42(tmp); } @ifdef IA64 -:PUSH simm8_16 is vexMode=0 & addrsize=2 & opsize=0 & byte=0x6a; simm8_16 { tmp:2=simm8_16; push82(tmp); } +:PUSH simm8_16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x6a; simm8_16 { tmp:2=simm8_16; push82(tmp); } @endif :PUSH simm8_32 is vexMode=0 & addrsize=0 & opsize=1 & byte=0x6a; simm8_32 { tmp:4=simm8_32; push24(tmp); } :PUSH simm8_32 is vexMode=0 & addrsize=1 & opsize=1 & byte=0x6a; simm8_32 { tmp:4=simm8_32; push44(tmp); } @ifdef IA64 -:PUSH simm8_64 is vexMode=0 & addrsize=2 & opsize=1 & byte=0x6a; simm8_64 { tmp:8=simm8_64; push88(tmp); } -:PUSH simm8_64 is vexMode=0 & addrsize=2 & opsize=2 & byte=0x6a; simm8_64 { tmp:8=simm8_64; push88(tmp); } +:PUSH simm8_64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0x6a; simm8_64 { tmp:8=simm8_64; push88(tmp); } +:PUSH simm8_64 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0x6a; simm8_64 { tmp:8=simm8_64; push88(tmp); } @endif :PUSH simm16_16 is vexMode=0 & addrsize=0 & opsize=0 & byte=0x68; simm16_16 { tmp:2=simm16_16; push22(tmp); } :PUSH simm16_16 is vexMode=0 & addrsize=1 & opsize=0 & byte=0x68; simm16_16 { tmp:2=simm16_16; push42(tmp); } @ifdef IA64 -:PUSH simm16_16 is vexMode=0 & addrsize=2 & opsize=0 & byte=0x68; simm16_16 { tmp:2=simm16_16; push82(tmp); } +:PUSH simm16_16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x68; simm16_16 { tmp:2=simm16_16; push82(tmp); } @endif :PUSH imm32 is vexMode=0 & addrsize=0 & opsize=1 & byte=0x68; imm32 { tmp:4=imm32; push24(tmp); } :PUSH imm32 is vexMode=0 & addrsize=1 & opsize=1 & byte=0x68; imm32 { tmp:4=imm32; push44(tmp); } @ifdef IA64 -:PUSH simm32 is vexMode=0 & addrsize=2 & opsize=1 & byte=0x68; simm32 { tmp:8=simm32; push88(tmp); } -:PUSH simm32 is vexMode=0 & addrsize=2 & opsize=2 & byte=0x68; simm32 { tmp:8=simm32; push88(tmp); } +:PUSH simm32 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0x68; simm32 { tmp:8=simm32; push88(tmp); } +:PUSH simm32 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0x68; simm32 { tmp:8=simm32; push88(tmp); } @endif :PUSH CS is vexMode=0 & addrsize=0 & byte=0xe & CS { push22(CS); } @@ -3368,12 +3367,12 @@ define pcodeop ptwrite; :PUSH FS is vexMode=0 & addrsize=0 & byte=0xf; byte=0xa0 & FS { push22(FS); } :PUSH FS is vexMode=0 & addrsize=1 & byte=0xf; byte=0xa0 & FS { pushseg44(FS); } @ifdef IA64 -:PUSH FS is vexMode=0 & addrsize=2 & byte=0xf; byte=0xa0 & FS { pushseg88(FS); } +:PUSH FS is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xf; byte=0xa0 & FS { pushseg88(FS); } @endif :PUSH GS is vexMode=0 & addrsize=0 & byte=0xf; byte=0xa8 & GS { push22(GS); } :PUSH GS is vexMode=0 & addrsize=1 & byte=0xf; byte=0xa8 & GS { pushseg44(GS); } @ifdef IA64 -:PUSH GS is vexMode=0 & addrsize=2 & byte=0xf; byte=0xa8 & GS { pushseg88(GS); } +:PUSH GS is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0xf; byte=0xa8 & GS { pushseg88(GS); } @endif :PUSHA is vexMode=0 & addrsize=0 & opsize=0 & byte=0x60 { local tmp=SP; push22(AX); push22(CX); push22(DX); push22(BX); push22(tmp); push22(BP); push22(SI); push22(DI); } @@ -3386,8 +3385,8 @@ define pcodeop ptwrite; :PUSHFD is vexMode=0 & addrsize=0 & opsize=1 & byte=0x9c { packflags(eflags); packeflags(eflags); push24(eflags); } :PUSHFD is vexMode=0 & addrsize=1 & opsize=1 & byte=0x9c { packflags(eflags); packeflags(eflags); push44(eflags); } @ifdef IA64 -:PUSHF is vexMode=0 & addrsize=2 & opsize=0 & byte=0x9c { packflags(flags); push82(flags); } -:PUSHFQ is vexMode=0 & addrsize=2 & byte=0x9c { packflags(rflags); packeflags(rflags); push88(rflags); } +:PUSHF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0x9c { packflags(flags); push82(flags); } +:PUSHFQ is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x9c { packflags(rflags); packeflags(rflags); push88(rflags); } @endif :RCL rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=2 ... { local tmpCF = CF; CF = rm8 s< 0; rm8 = (rm8 << 1) | tmpCF; OF = CF ^ (rm8 s< 0); } @@ -3400,9 +3399,9 @@ define pcodeop ptwrite; :RCL rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=2 ... { local cnt=CL&0x1f; tmp:8=(zext(CF)<<32)|zext(rm32); tmp=(tmp<>(33-cnt)); rm32=tmp(0); CF=(tmp&0x100000000)!=0; build check_rm32_dest; } :RCL rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=2 ... ; imm8 { local cnt=imm8&0x1f; tmp:8=(zext(CF)<<32)|zext(rm32); tmp=(tmp<>(33-cnt)); rm32=tmp(0); CF=(tmp&0x100000000)!=0; build check_rm32_dest; } @ifdef IA64 -:RCL rm64,n1 is vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=2 ... { local tmpCF=CF; CF=rm64 s< 0; rm64=(rm64<<1)|zext(tmpCF); OF=CF^(rm64 s< 0);} -:RCL rm64,CL is vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=2 ... { local cnt=CL&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp<>(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } -:RCL rm64,imm8 is vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=2 ... ; imm8 { local cnt=imm8&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp<>(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } +:RCL rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=2 ... { local tmpCF=CF; CF=rm64 s< 0; rm64=(rm64<<1)|zext(tmpCF); OF=CF^(rm64 s< 0);} +:RCL rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=2 ... { local cnt=CL&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp<>(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } +:RCL rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=2 ... ; imm8 { local cnt=imm8&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp<>(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } @endif :RCR rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=3 ... { local tmpCF=CF; OF=rm8 s< 0; CF=(rm8&1)!=0; rm8=(rm8>>1)|(tmpCF<<7); OF=OF^(rm8 s< 0); } @@ -3415,19 +3414,19 @@ define pcodeop ptwrite; :RCR rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=3 ... { local cnt=CL&0x1f; tmp:8=(zext(CF)<<32)|zext(rm32); tmp=(tmp>>cnt)|(tmp<<(33-cnt)); rm32=tmp(0); CF=(tmp&0x100000000)!=0; build check_rm32_dest; } :RCR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=3 ... ; imm8 { local cnt=imm8&0x1f; tmp:8=(zext(CF)<<32)|zext(rm32); tmp=(tmp>>cnt)|(tmp<<(33-cnt)); rm32=tmp(0); CF=(tmp&0x100000000)!=0; build check_rm32_dest; } @ifdef IA64 -:RCR rm64,n1 is vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=3 ... { local tmpCF=CF; OF=rm64 s< 0; CF=(rm64&1)!=0; rm64=(rm64>>1)|(zext(tmpCF)<<63); OF=OF^(rm64 s< 0); } -:RCR rm64,CL is vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=3 ... { local cnt=CL&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp>>cnt)|(tmp<<(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } -:RCR rm64,imm8 is vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=3 ... ; imm8 { local cnt=imm8&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp>>cnt)|(tmp<<(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } +:RCR rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=3 ... { local tmpCF=CF; OF=rm64 s< 0; CF=(rm64&1)!=0; rm64=(rm64>>1)|(zext(tmpCF)<<63); OF=OF^(rm64 s< 0); } +:RCR rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=3 ... { local cnt=CL&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp>>cnt)|(tmp<<(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } +:RCR rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=3 ... ; imm8 { local cnt=imm8&0x3f; tmp:16=(zext(CF)<<64)|zext(rm64); tmp=(tmp>>cnt)|(tmp<<(65-cnt)); rm64=tmp(0); CF=(tmp&0x1000000000000000)!=0; } @endif @ifdef IA64 define pcodeop readfsbase; :RDFSBASE r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=0 & r32 { r32 = readfsbase(); } -:RDFSBASE r64 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=0 & r64 { r64 = readfsbase(); } +:RDFSBASE r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=0 & r64 { r64 = readfsbase(); } define pcodeop readgsbase; :RDGSBASE r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=1 & r32 { r32 = readgsbase(); } -:RDGSBASE r64 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=1 & r64 { r64 = readgsbase(); } +:RDGSBASE r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=1 & r64 { r64 = readgsbase(); } @endif define pcodeop rdmsr; @@ -3440,7 +3439,7 @@ define pcodeop rdmsr; define pcodeop readPID; :RDPID r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xc7; reg_opcode=7 & r32 { r32 = readPID(); } @ifdef IA64 -:RDPID r64 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xc7; reg_opcode=7 & r64 { r64 = readPID(); } +:RDPID r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xc7; reg_opcode=7 & r64 { r64 = readPID(); } @endif define pcodeop rdpkru_u32; @@ -3452,49 +3451,46 @@ define pcodeop rdpmc; define pcodeop rdtsc; :RDTSC is vexMode=0 & byte=0xf; byte=0x31 { tmp:8 = rdtsc(); EDX = tmp(4); EAX = tmp(0); } -@ifndef IA64 -:RET is vexMode=0 & addrsize=0 & opsize=0 & byte=0xc3 { pop22(IP); EIP=segment(CS,IP); return [EIP]; } -:RET is vexMode=0 & addrsize=1 & opsize=0 & byte=0xc3 { pop42(IP); EIP=zext(IP); return [EIP]; } -:RET is vexMode=0 & addrsize=0 & opsize=1 & byte=0xc3 { pop24(EIP); return [EIP]; } -:RET is vexMode=0 & addrsize=1 & opsize=1 & byte=0xc3 { pop44(EIP); return [EIP]; } -@else -:RET is vexMode=0 & byte=0xc3 { pop88(RIP); return [RIP]; } +:RET is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0xc3 { pop22(IP); EIP=segment(CS,IP); return [EIP]; } +:RET is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0xc3 { pop42(IP); EIP=zext(IP); return [EIP]; } +:RET is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0xc3 { pop24(EIP); return [EIP]; } +:RET is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0xc3 { pop44(EIP); return [EIP]; } +@ifdef IA64 +:RET is $(LONGMODE_ON) & vexMode=0 & byte=0xc3 { pop88(RIP); return [RIP]; } @endif :RETF is vexMode=0 & addrsize=0 & opsize=0 & byte=0xcb { pop22(IP); pop22(CS); EIP = segment(CS,IP); return [EIP]; } -@ifndef IA64 -:RETF is vexMode=0 & addrsize=1 & opsize=0 & byte=0xcb { pop42(IP); EIP=zext(IP); pop42(CS); return [EIP]; } -@else -:RETF is vexMode=0 & addrsize=1 & opsize=0 & byte=0xcb { pop82(IP); RIP=zext(IP); pop82(CS); return [RIP]; } -:RETF is vexMode=0 & addrsize=2 & opsize=0 & byte=0xcb { pop82(IP); RIP=zext(IP); pop82(CS); return [RIP]; } +:RETF is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0xcb { pop42(IP); EIP=zext(IP); pop42(CS); return [EIP]; } +@ifdef IA64 +:RETF is $(LONGMODE_ON) & vexMode=0 & addrsize=1 & opsize=0 & byte=0xcb { pop82(IP); RIP=zext(IP); pop82(CS); return [RIP]; } +:RETF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xcb { pop82(IP); RIP=zext(IP); pop82(CS); return [RIP]; } @endif :RETF is vexMode=0 & addrsize=0 & opsize=1 & byte=0xcb { pop24(EIP); tmp:4=0; pop24(tmp); CS=tmp(0); return [EIP]; } :RETF is vexMode=0 & addrsize=1 & opsize=1 & byte=0xcb { pop44(EIP); tmp:4=0; pop44(tmp); CS=tmp(0); return [EIP]; } @ifdef IA64 -:RETF is vexMode=0 & addrsize=2 & opsize=1 & byte=0xcb { pop48(EIP); RIP=zext(EIP); tmp:4=0; pop44(tmp); CS=tmp(0); return [RIP]; } -:RETF is vexMode=0 & addrsize=2 & opsize=2 & byte=0xcb { pop88(RIP); tmp:8=0; pop88(tmp); CS=tmp(0); return [RIP]; } +:RETF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0xcb { pop48(EIP); RIP=zext(EIP); tmp:4=0; pop44(tmp); CS=tmp(0); return [RIP]; } +:RETF is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0xcb { pop88(RIP); tmp:8=0; pop88(tmp); CS=tmp(0); return [RIP]; } @endif -@ifndef IA64 -:RET imm16 is vexMode=0 & addrsize=0 & opsize=0 & byte=0xc2; imm16 { pop22(IP); EIP=zext(IP); SP=SP+imm16; return [EIP]; } -:RET imm16 is vexMode=0 & addrsize=1 & opsize=0 & byte=0xc2; imm16 { pop42(IP); EIP=zext(IP); ESP=ESP+imm16; return [EIP]; } -:RET imm16 is vexMode=0 & addrsize=0 & opsize=1 & byte=0xc2; imm16 { pop24(EIP); SP=SP+imm16; return [EIP]; } -:RET imm16 is vexMode=0 & addrsize=1 & opsize=1 & byte=0xc2; imm16 { pop44(EIP); ESP=ESP+imm16; return [EIP]; } -@else -:RET imm16 is vexMode=0 & byte=0xc2; imm16 { pop88(RIP); RSP=RSP+imm16; return [RIP]; } +:RET imm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=0 & byte=0xc2; imm16 { pop22(IP); EIP=zext(IP); SP=SP+imm16; return [EIP]; } +:RET imm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=0 & byte=0xc2; imm16 { pop42(IP); EIP=zext(IP); ESP=ESP+imm16; return [EIP]; } +:RET imm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=0 & opsize=1 & byte=0xc2; imm16 { pop24(EIP); SP=SP+imm16; return [EIP]; } +:RET imm16 is $(LONGMODE_OFF) & vexMode=0 & addrsize=1 & opsize=1 & byte=0xc2; imm16 { pop44(EIP); ESP=ESP+imm16; return [EIP]; } +@ifdef IA64 +:RET imm16 is $(LONGMODE_ON) & vexMode=0 & byte=0xc2; imm16 { pop88(RIP); RSP=RSP+imm16; return [RIP]; } @endif :RETF imm16 is vexMode=0 & addrsize=0 & opsize=0 & byte=0xca; imm16 { pop22(IP); EIP=zext(IP); pop22(CS); SP=SP+imm16; return [EIP]; } :RETF imm16 is vexMode=0 & addrsize=1 & opsize=0 & byte=0xca; imm16 { pop42(IP); EIP=zext(IP); pop42(CS); ESP=ESP+imm16; return [EIP]; } @ifdef IA64 -:RETF imm16 is vexMode=0 & addrsize=2 & opsize=0 & byte=0xca; imm16 { pop42(IP); RIP=zext(IP); pop42(CS); RSP=RSP+imm16; return [RIP]; } +:RETF imm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=0 & byte=0xca; imm16 { pop42(IP); RIP=zext(IP); pop42(CS); RSP=RSP+imm16; return [RIP]; } @endif :RETF imm16 is vexMode=0 & addrsize=0 & opsize=1 & byte=0xca; imm16 { pop24(EIP); tmp:4=0; pop24(tmp); CS=tmp(0); SP=SP+imm16; return [EIP]; } :RETF imm16 is vexMode=0 & addrsize=1 & opsize=1 & byte=0xca; imm16 { pop44(EIP); tmp:4=0; pop44(tmp); CS=tmp(0); ESP=ESP+imm16; return [EIP]; } @ifdef IA64 -:RETF imm16 is vexMode=0 & addrsize=2 & opsize=1 & byte=0xca; imm16 { pop44(EIP); tmp:4=0; pop44(tmp); RIP=zext(EIP); CS=tmp(0); RSP=RSP+imm16; return [RIP]; } -:RETF imm16 is vexMode=0 & addrsize=2 & opsize=2 & byte=0xca; imm16 { pop88(RIP); tmp:8=0; pop88(tmp); CS=tmp(0); RSP=RSP+imm16; return [RIP]; } +:RETF imm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=1 & byte=0xca; imm16 { pop44(EIP); tmp:4=0; pop44(tmp); RIP=zext(EIP); CS=tmp(0); RSP=RSP+imm16; return [RIP]; } +:RETF imm16 is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & opsize=2 & byte=0xca; imm16 { pop88(RIP); tmp:8=0; pop88(tmp); CS=tmp(0); RSP=RSP+imm16; return [RIP]; } @endif :ROL rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=0 ... { CF = rm8 s< 0; rm8 = (rm8 << 1) | CF; OF = CF ^ (rm8 s< 0); } @@ -3507,9 +3503,9 @@ define pcodeop rdtsc; :ROL rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=0 ... { local cnt = CL & 0x1f; rm32 = (rm32 << cnt) | (rm32 >> (32 - cnt)); rolflags(rm32,cnt); build check_rm32_dest; } :ROL rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=0 ... ; imm8 { local cnt = imm8 & 0x1f; rm32 = (rm32 << cnt) | (rm32 >> (32 - cnt)); rolflags(rm32,cnt); build check_rm32_dest; } @ifdef IA64 -:ROL rm64,n1 is vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=0 ... { CF = rm64 s< 0; rm64 = (rm64 << 1) | zext(CF); OF = CF ^ (rm64 s< 0); } -:ROL rm64,CL is vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=0 ... { local cnt = CL & 0x3f; rm64 = (rm64 << cnt) | (rm64 >> (64 - cnt)); rolflags(rm64,cnt);} -:ROL rm64,imm8 is vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=0 ... ; imm8 { local cnt = imm8 & 0x3f; rm64 = (rm64 << cnt) | (rm64 >> (64 - cnt)); rolflags(rm64,cnt);} +:ROL rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=0 ... { CF = rm64 s< 0; rm64 = (rm64 << 1) | zext(CF); OF = CF ^ (rm64 s< 0); } +:ROL rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=0 ... { local cnt = CL & 0x3f; rm64 = (rm64 << cnt) | (rm64 >> (64 - cnt)); rolflags(rm64,cnt);} +:ROL rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=0 ... ; imm8 { local cnt = imm8 & 0x3f; rm64 = (rm64 << cnt) | (rm64 >> (64 - cnt)); rolflags(rm64,cnt);} @endif :ROR rm8,n1 is vexMode=0 & byte=0xD0; rm8 & n1 & reg_opcode=1 ... { CF = rm8 & 1; rm8 = (rm8 >> 1) | (CF << 7); OF = ((rm8 & 0x40) != 0) ^ (rm8 s< 0); } @@ -3522,9 +3518,9 @@ define pcodeop rdtsc; :ROR rm32,CL is vexMode=0 & opsize=1 & byte=0xD3; CL & rm32 & check_rm32_dest ... & reg_opcode=1 ... { local cnt = CL & 0x1f; rm32 = (rm32 >> cnt) | (rm32 << (32 - cnt)); rorflags(rm32,cnt); build check_rm32_dest; } :ROR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=1 ... ; imm8 { local cnt = imm8 & 0x1f; rm32 = (rm32 >> cnt) | (rm32 << (32 - cnt)); rorflags(rm32,cnt); build check_rm32_dest; } @ifdef IA64 -:ROR rm64,n1 is vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=1 ... { CF=(rm64&1)!=0; rm64=(rm64>>1)|(zext(CF)<<63); OF=((rm64&0x4000000000000000)!=0) ^ (rm64 s< 0); } -:ROR rm64,CL is vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=1 ... { local cnt = CL & 0x3f; rm64 = (rm64 >> cnt) | (rm64 << (64 - cnt)); rorflags(rm64,cnt);} -:ROR rm64,imm8 is vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=1 ... ; imm8 { local cnt = imm8 & 0x3f; rm64 = (rm64 >> cnt) | (rm64 << (64 - cnt)); rorflags(rm64,cnt);} +:ROR rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=1 ... { CF=(rm64&1)!=0; rm64=(rm64>>1)|(zext(CF)<<63); OF=((rm64&0x4000000000000000)!=0) ^ (rm64 s< 0); } +:ROR rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=1 ... { local cnt = CL & 0x3f; rm64 = (rm64 >> cnt) | (rm64 << (64 - cnt)); rorflags(rm64,cnt);} +:ROR rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=1 ... ; imm8 { local cnt = imm8 & 0x3f; rm64 = (rm64 >> cnt) | (rm64 << (64 - cnt)); rorflags(rm64,cnt);} @endif define pcodeop smm_restore_state; @@ -3555,10 +3551,10 @@ define pcodeop smm_restore_state; :SAR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=7 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm32; rm32 = rm32 s>> count; build check_rm32_dest; sarflags(tmp, rm32,count); shiftresultflags(rm32,count); } @ifdef IA64 -:SAR rm64,n1 is vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=7 ... { CF = (rm64 & 1) != 0; OF = 0; rm64 = rm64 s>> 1; resultflags(rm64); } -:SAR rm64,CL is vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=7 ... { local count = CL & 0x3f; local tmp = rm64; rm64 = rm64 s>> count; +:SAR rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & reg_opcode=7 ... { CF = (rm64 & 1) != 0; OF = 0; rm64 = rm64 s>> 1; resultflags(rm64); } +:SAR rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=7 ... { local count = CL & 0x3f; local tmp = rm64; rm64 = rm64 s>> count; sarflags(tmp, rm64,count); shiftresultflags(rm64,count); } -:SAR rm64,imm8 is vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=7 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = rm64 s>> count; +:SAR rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=7 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = rm64 s>> count; sarflags(tmp, rm64,count); shiftresultflags(rm64,count); } @endif @@ -3566,40 +3562,40 @@ define pcodeop smm_restore_state; :SBB AX,imm16 is vexMode=0 & opsize=0 & byte=0x1d; AX & imm16 { subCarryFlags( AX, imm16 ); resultflags(AX); } :SBB EAX,imm32 is vexMode=0 & opsize=1 & byte=0x1d; EAX & check_EAX_dest & imm32 { subCarryFlags( EAX, imm32 ); build check_EAX_dest; resultflags(EAX); } @ifdef IA64 -:SBB RAX,imm32 is vexMode=0 & opsize=2 & byte=0x1d; RAX & imm32 { subCarryFlags( RAX, imm32 ); resultflags(RAX); } +:SBB RAX,imm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x1d; RAX & imm32 { subCarryFlags( RAX, imm32 ); resultflags(RAX); } @endif :SBB rm8,imm8 is vexMode=0 & (byte=0x80 | byte=0x82); rm8 & reg_opcode=3 ...; imm8 { subCarryFlags( rm8, imm8 ); resultflags(rm8); } :SBB rm16,imm16 is vexMode=0 & opsize=0 & byte=0x81; rm16 & reg_opcode=3 ...; imm16 { subCarryFlags( rm16, imm16 ); resultflags(rm16); } :SBB rm32,imm32 is vexMode=0 & opsize=1 & byte=0x81; rm32 & check_rm32_dest ... & reg_opcode=3 ...; imm32 { subCarryFlags( rm32, imm32 ); build check_rm32_dest; resultflags(rm32); } @ifdef IA64 -:SBB rm64,imm32 is vexMode=0 & opsize=2 & byte=0x81; rm64 & reg_opcode=3 ...; imm32 { subCarryFlags( rm64, imm32 ); resultflags(rm64); } +:SBB rm64,imm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; rm64 & reg_opcode=3 ...; imm32 { subCarryFlags( rm64, imm32 ); resultflags(rm64); } @endif :SBB rm16,simm8_16 is vexMode=0 & opsize=0 & byte=0x83; rm16 & reg_opcode=3 ...; simm8_16 { subCarryFlags( rm16, simm8_16 ); resultflags(rm16); } :SBB rm32,simm8_32 is vexMode=0 & opsize=1 & byte=0x83; rm32 & check_rm32_dest ... & reg_opcode=3 ...; simm8_32 { subCarryFlags( rm32, simm8_32 ); build check_rm32_dest; resultflags(rm32); } @ifdef IA64 -:SBB rm64,simm8_64 is vexMode=0 & opsize=2 & byte=0x83; rm64 & reg_opcode=3 ...; simm8_64 { subCarryFlags( rm64, simm8_64 ); resultflags(rm64); } +:SBB rm64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; rm64 & reg_opcode=3 ...; simm8_64 { subCarryFlags( rm64, simm8_64 ); resultflags(rm64); } @endif :SBB rm8,Reg8 is vexMode=0 & byte=0x18; rm8 & Reg8 ... { subCarryFlags( rm8, Reg8 ); resultflags(rm8); } :SBB rm16,Reg16 is vexMode=0 & opsize=0 & byte=0x19; rm16 & Reg16 ... { subCarryFlags( rm16, Reg16 ); resultflags(rm16); } :SBB rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x19; rm32 & check_rm32_dest ... & Reg32 ... { subCarryFlags( rm32, Reg32 ); build check_rm32_dest; resultflags(rm32); } @ifdef IA64 -:SBB rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x19; rm64 & Reg64 ... { subCarryFlags( rm64, Reg64 ); resultflags(rm64); } +:SBB rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x19; rm64 & Reg64 ... { subCarryFlags( rm64, Reg64 ); resultflags(rm64); } @endif :SBB Reg8,rm8 is vexMode=0 & byte=0x1a; rm8 & Reg8 ... { subCarryFlags( Reg8, rm8 ); resultflags(Reg8); } :SBB Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x1b; rm16 & Reg16 ... { subCarryFlags( Reg16, rm16 ); resultflags(Reg16); } :SBB Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x1b; rm32 & Reg32 ... & check_Reg32_dest ... { subCarryFlags( Reg32, rm32 ); build check_Reg32_dest; resultflags(Reg32); } @ifdef IA64 -:SBB Reg64,rm64 is vexMode=0 & opsize=2 & byte=0x1b; rm64 & Reg64 ... { subCarryFlags( Reg64, rm64 ); resultflags(Reg64); } +:SBB Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x1b; rm64 & Reg64 ... { subCarryFlags( Reg64, rm64 ); resultflags(Reg64); } @endif :SCASB^repe^repetail eseDI1 is vexMode=0 & repe & repetail & byte=0xae & eseDI1 { build repe; build eseDI1; subflags(AL,eseDI1); local diff=AL-eseDI1; resultflags(diff); build repetail; } :SCASW^repe^repetail eseDI2 is vexMode=0 & repe & repetail & opsize=0 & byte=0xaf & eseDI2 { build repe; build eseDI2; subflags(AX,eseDI2); local diff=AX-eseDI2; resultflags(diff); build repetail; } :SCASD^repe^repetail eseDI4 is vexMode=0 & repe & repetail & opsize=1 & byte=0xaf & eseDI4 { build repe; build eseDI4; subflags(EAX,eseDI4); local diff=EAX-eseDI4; resultflags(diff); build repetail; } @ifdef IA64 -:SCASQ^repe^repetail eseDI8 is vexMode=0 & repe & repetail & opsize=2 & byte=0xaf & eseDI8 { build repe; build eseDI8; subflags(RAX,eseDI8); local diff=RAX-eseDI8; resultflags(diff); build repetail; } +:SCASQ^repe^repetail eseDI8 is $(LONGMODE_ON) & vexMode=0 & repe & repetail & opsize=2 & byte=0xaf & eseDI8 { build repe; build eseDI8; subflags(RAX,eseDI8); local diff=RAX-eseDI8; resultflags(diff); build repetail; } @endif :SET^cc rm8 is vexMode=0 & byte=0xf; row=9 & cc; rm8 { rm8 = cc; } @@ -3616,7 +3612,7 @@ define pcodeop smm_restore_state; } @ifdef IA64 -:SGDT m64 is vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=0 ) ... & m64 +:SGDT m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=0 ) ... & m64 { m64 = GlobalDescriptorTableRegister(); } @@ -3639,10 +3635,10 @@ define pcodeop smm_restore_state; :SHL rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & (reg_opcode=4|reg_opcode=6) ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm32; rm32 = rm32 << count; build check_rm32_dest; shlflags(tmp, rm32,count); shiftresultflags(rm32,count); } @ifdef IA64 -:SHL rm64,n1 is vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & (reg_opcode=4|reg_opcode=6) ... { CF = rm64 s< 0; rm64 = rm64 << 1; OF = CF ^ (rm64 s< 0); resultflags(rm64); } -:SHL rm64,CL is vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & (reg_opcode=4|reg_opcode=6) ... { local count = CL & 0x3f; local tmp = rm64; rm64 = rm64 << count; +:SHL rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 & (reg_opcode=4|reg_opcode=6) ... { CF = rm64 s< 0; rm64 = rm64 << 1; OF = CF ^ (rm64 s< 0); resultflags(rm64); } +:SHL rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & (reg_opcode=4|reg_opcode=6) ... { local count = CL & 0x3f; local tmp = rm64; rm64 = rm64 << count; shlflags(tmp, rm64,count); shiftresultflags(rm64,count); } -:SHL rm64,imm8 is vexMode=0 & opsize=2 & byte=0xC1; rm64 & (reg_opcode=4|reg_opcode=6) ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = rm64 << count; +:SHL rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & (reg_opcode=4|reg_opcode=6) ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = rm64 << count; shlflags(tmp, rm64,count); shiftresultflags(rm64,count); } @endif @@ -3659,10 +3655,10 @@ define pcodeop smm_restore_state; rm32 = (rm32 << count) | (Reg32 >> (32 - count)); build check_rm32_dest; shlflags(tmp,rm32,count); shiftresultflags(rm32,count); } @ifdef IA64 -:SHLD rm64,Reg64,imm8 is vexMode=0 & opsize=2; byte=0x0F; byte=0xA4; rm64 & Reg64 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; +:SHLD rm64,Reg64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x0F; byte=0xA4; rm64 & Reg64 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = (rm64 << count) | (Reg64 >> (64 - count)); shlflags(tmp,rm64,count); shiftresultflags(rm64,count); } -:SHLD rm64,Reg64,CL is vexMode=0 & opsize=2; byte=0x0F; byte=0xA5; CL & rm64 & Reg64 ... { local count = CL & 0x3f; local tmp = rm64; +:SHLD rm64,Reg64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x0F; byte=0xA5; CL & rm64 & Reg64 ... { local count = CL & 0x3f; local tmp = rm64; rm64 = (rm64 << count) | (Reg64 >> (64 - count)); shlflags(tmp,rm64,count); shiftresultflags(rm64,count); } @endif @@ -3680,10 +3676,10 @@ define pcodeop smm_restore_state; rm32 = (rm32 >> count) | (Reg32 << (32 - count)); build check_rm32_dest; shrdflags(tmp,rm32,count); shiftresultflags(rm32,count); } @ifdef IA64 -:SHRD rm64,Reg64,imm8 is vexMode=0 & opsize=2; byte=0x0F; byte=0xAC; rm64 & Reg64 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; +:SHRD rm64,Reg64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x0F; byte=0xAC; rm64 & Reg64 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = (rm64 >> count) | (Reg64 << (64 - count)); shrdflags(tmp,rm64,count); shiftresultflags(rm64,count); } -:SHRD rm64,Reg64,CL is vexMode=0 & opsize=2; byte=0x0F; byte=0xAD; CL & rm64 & Reg64 ... { local count = CL & 0x3f; local tmp = rm64; +:SHRD rm64,Reg64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x0F; byte=0xAD; CL & rm64 & Reg64 ... { local count = CL & 0x3f; local tmp = rm64; rm64 = (rm64 >> count) | (Reg64 << (64 - count)); shrdflags(tmp,rm64,count); shiftresultflags(rm64,count); } @endif @@ -3704,10 +3700,10 @@ define pcodeop smm_restore_state; :SHR rm32,imm8 is vexMode=0 & opsize=1 & byte=0xC1; rm32 & check_rm32_dest ... & reg_opcode=5 ... ; imm8 { local count = imm8 & 0x1f; local tmp = rm32; rm32 = rm32 >> count; build check_rm32_dest; shrflags(tmp, rm32,count); shiftresultflags(rm32,count); } @ifdef IA64 -:SHR rm64,n1 is vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 ®_opcode=5 ... { CF = (rm64 & 1) != 0; OF = 0; rm64 = rm64 >> 1; resultflags(rm64); } -:SHR rm64,CL is vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=5 ... { local count = CL & 0x3f; local tmp = rm64; rm64 = rm64 >> count; +:SHR rm64,n1 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD1; rm64 & n1 ®_opcode=5 ... { CF = (rm64 & 1) != 0; OF = 0; rm64 = rm64 >> 1; resultflags(rm64); } +:SHR rm64,CL is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xD3; CL & rm64 & reg_opcode=5 ... { local count = CL & 0x3f; local tmp = rm64; rm64 = rm64 >> count; shrflags(tmp, rm64,count); shiftresultflags(rm64,count); } -:SHR rm64,imm8 is vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=5 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = rm64 >> count; +:SHR rm64,imm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xC1; rm64 & reg_opcode=5 ... ; imm8 { local count = imm8 & 0x3f; local tmp = rm64; rm64 = rm64 >> count; shrflags(tmp, rm64,count); shiftresultflags(rm64,count); } @endif @@ -3721,7 +3717,7 @@ define pcodeop smm_restore_state; m32 = InterruptDescriptorTableRegister(); } @ifdef IA64 -:SIDT m64 is vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=1 ) ... & m64 +:SIDT m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x1; ( mod != 0b11 & reg_opcode=1 ) ... & m64 { m64 = InterruptDescriptorTableRegister(); } @@ -3739,7 +3735,7 @@ define pcodeop skinit; rm32 = LocalDescriptorTableRegister(); } @ifdef IA64 -:SLDT rm64 is vexMode=0 & opsize=2 & byte=0xf; byte=0x0; rm64 & reg_opcode=0 ... +:SLDT rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x0; rm64 & reg_opcode=0 ... { rm64 = LocalDescriptorTableRegister(); } @@ -3748,7 +3744,7 @@ define pcodeop skinit; :SMSW rm16 is vexMode=0 & opsize=0 & byte=0xf; byte=0x01; rm16 & reg_opcode=4 ... { rm16 = CR0:2; } :SMSW rm32 is vexMode=0 & opsize=1 & byte=0xf; byte=0x01; rm32 & reg_opcode=4 ... { rm32 = zext(CR0:2); } @ifdef IA64 -:SMSW rm64 is vexMode=0 & opsize=2 & byte=0xf; byte=0x01; rm64 & reg_opcode=4 ... { rm64 = CR0; } +:SMSW rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0xf; byte=0x01; rm64 & reg_opcode=4 ... { rm64 = CR0; } @endif :STAC is vexMode=0 & byte=0x0f; byte=0x01; byte=0xcb { AC = 1; } @@ -3766,7 +3762,7 @@ define pcodeop skinit; :STOSW^rep^reptail eseDI2 is vexMode=0 & rep & reptail & opsize=0 & byte=0xab & eseDI2 { build rep; build eseDI2; eseDI2=AX; build reptail; } :STOSD^rep^reptail eseDI4 is vexMode=0 & rep & reptail & opsize=1 & byte=0xab & eseDI4 { build rep; build eseDI4; eseDI4=EAX; build reptail; } @ifdef IA64 -:STOSQ^rep^reptail eseDI8 is vexMode=0 & rep & reptail & opsize=2 & byte=0xab & eseDI8 { build rep; build eseDI8; eseDI8=RAX; build reptail; } +:STOSQ^rep^reptail eseDI8 is $(LONGMODE_ON) & vexMode=0 & rep & reptail & opsize=2 & byte=0xab & eseDI8 { build rep; build eseDI8; eseDI8=RAX; build reptail; } @endif :STR rm16 is vexMode=0 & byte=0xf; byte=0x0; rm16 & reg_opcode=1 ... { rm16 = TaskRegister(); } @@ -3775,30 +3771,30 @@ define pcodeop skinit; :SUB AX,imm16 is vexMode=0 & opsize=0 & byte=0x2d; AX & imm16 { subflags( AX,imm16); AX = AX - imm16; resultflags( AX); } :SUB EAX,imm32 is vexMode=0 & opsize=1 & byte=0x2d; EAX & check_EAX_dest & imm32 { subflags( EAX,imm32); EAX = EAX - imm32; build check_EAX_dest; resultflags( EAX); } @ifdef IA64 -:SUB RAX,simm32 is vexMode=0 & opsize=2 & byte=0x2d; RAX & simm32 { subflags( RAX,simm32); RAX = RAX - simm32; resultflags( RAX); } +:SUB RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x2d; RAX & simm32 { subflags( RAX,simm32); RAX = RAX - simm32; resultflags( RAX); } @endif :SUB spec_rm8,imm8 is vexMode=0 & (byte=0x80 | byte=0x82); spec_rm8 & reg_opcode=5 ...; imm8 { subflags( spec_rm8,imm8 ); spec_rm8 = spec_rm8 - imm8; resultflags( spec_rm8); } :SUB spec_rm16,imm16 is vexMode=0 & opsize=0 & byte=0x81; spec_rm16 & reg_opcode=5 ...; imm16 { subflags( spec_rm16,imm16); spec_rm16 = spec_rm16 - imm16; resultflags( spec_rm16); } :SUB spec_rm32,imm32 is vexMode=0 & opsize=1 & byte=0x81; spec_rm32 & check_rm32_dest ... & reg_opcode=5 ...; imm32 { subflags( spec_rm32,imm32); spec_rm32 = spec_rm32 - imm32; build check_rm32_dest; resultflags( spec_rm32); } @ifdef IA64 -:SUB spec_rm64,simm32 is vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=5 ...; simm32 { subflags( spec_rm64,simm32); spec_rm64 = spec_rm64 - simm32; resultflags( spec_rm64); } +:SUB spec_rm64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=5 ...; simm32 { subflags( spec_rm64,simm32); spec_rm64 = spec_rm64 - simm32; resultflags( spec_rm64); } @endif :SUB spec_rm16,simm8_16 is vexMode=0 & opsize=0 & byte=0x83; spec_rm16 & reg_opcode=5 ...; simm8_16 { subflags( spec_rm16,simm8_16); spec_rm16 = spec_rm16 - simm8_16; resultflags( spec_rm16); } :SUB spec_rm32,simm8_32 is vexMode=0 & opsize=1 & byte=0x83; spec_rm32 & check_rm32_dest ... & reg_opcode=5 ...; simm8_32 { subflags( spec_rm32,simm8_32); spec_rm32 = spec_rm32 - simm8_32; build check_rm32_dest; resultflags( spec_rm32); } @ifdef IA64 -:SUB spec_rm64,simm8_64 is vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=5 ...; simm8_64 { subflags( spec_rm64,simm8_64); spec_rm64 = spec_rm64 - simm8_64; resultflags( spec_rm64); } +:SUB spec_rm64,simm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=5 ...; simm8_64 { subflags( spec_rm64,simm8_64); spec_rm64 = spec_rm64 - simm8_64; resultflags( spec_rm64); } @endif :SUB rm8,Reg8 is vexMode=0 & byte=0x28; rm8 & Reg8 ... { subflags( rm8,Reg8 ); rm8 = rm8 - Reg8; resultflags( rm8); } :SUB rm16,Reg16 is vexMode=0 & opsize=0 & byte=0x29; rm16 & Reg16 ... { subflags( rm16,Reg16); rm16 = rm16 - Reg16; resultflags( rm16); } :SUB rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x29; rm32 & check_rm32_dest ... & Reg32 ... { subflags( rm32,Reg32); rm32 = rm32 - Reg32; build check_rm32_dest; resultflags( rm32); } @ifdef IA64 -:SUB rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x29; rm64 & Reg64 ... { subflags( rm64,Reg64); rm64 = rm64 - Reg64; resultflags( rm64); } +:SUB rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x29; rm64 & Reg64 ... { subflags( rm64,Reg64); rm64 = rm64 - Reg64; resultflags( rm64); } @endif :SUB Reg8,rm8 is vexMode=0 & byte=0x2a; rm8 & Reg8 ... { subflags( Reg8,rm8 ); Reg8 = Reg8 - rm8; resultflags( Reg8); } :SUB Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x2b; rm16 & Reg16 ... { subflags(Reg16,rm16 ); Reg16 = Reg16 - rm16; resultflags(Reg16); } :SUB Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x2b; rm32 & Reg32 ... & check_Reg32_dest ... { subflags(Reg32,rm32 ); Reg32 = Reg32 - rm32; build check_Reg32_dest; resultflags(Reg32); } @ifdef IA64 -:SUB Reg64,rm64 is vexMode=0 & opsize=2 & byte=0x2b; rm64 & Reg64 ... { subflags(Reg64,rm64 ); Reg64 = Reg64 - rm64; resultflags(Reg64); } +:SUB Reg64,rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x2b; rm64 & Reg64 ... { subflags(Reg64,rm64 ); Reg64 = Reg64 - rm64; resultflags(Reg64); } @endif :SYSENTER is vexMode=0 & byte=0x0f; byte=0x34 { sysenter(); } @@ -3826,19 +3822,19 @@ define pcodeop skinit; :TEST AX,imm16 is vexMode=0 & opsize=0; byte=0xA9; AX & imm16 { logicalflags(); local tmp = AX & imm16; resultflags(tmp); } :TEST EAX,imm32 is vexMode=0 & opsize=1; byte=0xA9; EAX & imm32 { logicalflags(); local tmp = EAX & imm32; resultflags(tmp); } @ifdef IA64 -:TEST RAX,simm32 is vexMode=0 & opsize=2; byte=0xA9; RAX & simm32 { logicalflags(); local tmp = RAX & simm32; resultflags(tmp); } +:TEST RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0xA9; RAX & simm32 { logicalflags(); local tmp = RAX & simm32; resultflags(tmp); } @endif :TEST spec_rm8,imm8 is vexMode=0 & byte=0xF6; spec_rm8 & (reg_opcode=0 | reg_opcode=1) ... ; imm8 { logicalflags(); local tmp = spec_rm8 & imm8; resultflags(tmp); } :TEST spec_rm16,imm16 is vexMode=0 & opsize=0; byte=0xF7; spec_rm16 & (reg_opcode=0 | reg_opcode=1) ... ; imm16 { logicalflags(); local tmp = spec_rm16 & imm16; resultflags(tmp); } :TEST spec_rm32,imm32 is vexMode=0 & opsize=1; byte=0xF7; spec_rm32 & (reg_opcode=0 | reg_opcode=1) ... ; imm32 { logicalflags(); local tmp = spec_rm32 & imm32; resultflags(tmp); } @ifdef IA64 -:TEST spec_rm64,simm32 is vexMode=0 & opsize=2; byte=0xF7; spec_rm64 & (reg_opcode=0 | reg_opcode=1) ... ; simm32 { logicalflags(); local tmp = spec_rm64 & simm32; resultflags(tmp); } +:TEST spec_rm64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0xF7; spec_rm64 & (reg_opcode=0 | reg_opcode=1) ... ; simm32 { logicalflags(); local tmp = spec_rm64 & simm32; resultflags(tmp); } @endif :TEST rm8,Reg8 is vexMode=0 & byte=0x84; rm8 & Reg8 ... { logicalflags(); local tmp = rm8 & Reg8; resultflags(tmp); } :TEST rm16,Reg16 is vexMode=0 & opsize=0; byte=0x85; rm16 & Reg16 ... { logicalflags(); local tmp = rm16 & Reg16; resultflags(tmp); } :TEST rm32,Reg32 is vexMode=0 & opsize=1; byte=0x85; rm32 & Reg32 ... { logicalflags(); local tmp = rm32 & Reg32; resultflags(tmp); } @ifdef IA64 -:TEST rm64,Reg64 is vexMode=0 & opsize=2; byte=0x85; rm64 & Reg64 ... { logicalflags(); local tmp = rm64 & Reg64; resultflags(tmp); } +:TEST rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2; byte=0x85; rm64 & Reg64 ... { logicalflags(); local tmp = rm64 & Reg64; resultflags(tmp); } @endif define pcodeop invalidInstructionException; @@ -3854,34 +3850,34 @@ define pcodeop invalidInstructionException; # AMD hardware assisted virtualization opcodes :VMLOAD EAX is vexMode=0 & addrsize=1 & byte=0x0f; byte=0x01; byte=0xda & EAX { vmload(EAX); } @ifdef IA64 -:VMLOAD RAX is vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xda & RAX { vmload(RAX); } +:VMLOAD RAX is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xda & RAX { vmload(RAX); } @endif :VMMCALL is vexMode=0 & byte=0x0f; byte=0x01; byte=0xd9 { vmmcall(); } # Limiting the effective address size to 32 and 64 bit. Surely we're not expecting a 16-bit VM address, are we? :VMRUN EAX is vexMode=0 & addrsize=1 & byte=0x0f; byte=0x01; byte=0xd8 & EAX { vmrun(EAX); } @ifdef IA64 -:VMRUN RAX is vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xd8 & RAX { vmrun(RAX); } +:VMRUN RAX is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xd8 & RAX { vmrun(RAX); } @endif # Limiting the effective address size to 32 and 64 bit. Surely we're not expecting a 16-bit VM address, are we? :VMSAVE EAX is vexMode=0 & addrsize=1 & byte=0x0f; byte=0x01; byte=0xdb & EAX { vmsave(EAX); } @ifdef IA64 -:VMSAVE RAX is vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xdb & RAX { vmsave(RAX); } +:VMSAVE RAX is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & byte=0x0f; byte=0x01; byte=0xdb & RAX { vmsave(RAX); } @endif # # # Intel hardware assisted virtualization opcodes @ifdef IA64 -:INVEPT Reg64, m128 is vexMode=0 & bit64=1 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x80; Reg64 ... & m128 { invept(Reg64, m128); } +:INVEPT Reg64, m128 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x80; Reg64 ... & m128 { invept(Reg64, m128); } @endif :INVEPT Reg32, m128 is vexMode=0 & bit64=0 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x80; Reg32 ... & m128 { invept(Reg32, m128); } @ifdef IA64 -:INVVPID Reg64, m128 is vexMode=0 & bit64=1 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x81; Reg64 ... & m128 { invvpid(Reg64, m128); } +:INVVPID Reg64, m128 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x81; Reg64 ... & m128 { invvpid(Reg64, m128); } @endif :INVVPID Reg32, m128 is vexMode=0 & bit64=0 & $(PRE_66) & byte=0x0f; byte=0x38; byte=0x81; Reg32 ... & m128 { invvpid(Reg32, m128); } :VMCALL is vexMode=0 & byte=0x0f; byte=0x01; byte=0xc1 { vmcall(); } @ifdef IA64 -:VMCLEAR m64 is vexMode=0 & $(PRE_66) & byte=0x0f; byte=0xc7; ( mod != 0b11 & reg_opcode=6 ) ... & m64 { vmclear(m64); } +:VMCLEAR m64 is $(LONGMODE_ON) & vexMode=0 & $(PRE_66) & byte=0x0f; byte=0xc7; ( mod != 0b11 & reg_opcode=6 ) ... & m64 { vmclear(m64); } @endif #TODO: invokes a VM function specified in EAX :VMFUNC EAX is vexMode=0 & byte=0x0f; byte=0x01; byte=0xd4 & EAX { vmfunc(EAX); } @@ -3899,11 +3895,11 @@ define pcodeop invalidInstructionException; :VMPTRST m64 is vexMode=0 & byte=0x0f; byte=0xc7; ( mod != 0b11 & reg_opcode=7 ) ... & m64 { vmptrst(m64); } :VMREAD rm32, Reg32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0x78; rm32 & check_rm32_dest ... & Reg32 ... { rm32 = vmread(Reg32); build check_rm32_dest; } @ifdef IA64 -:VMREAD rm64, Reg64 is vexMode=0 & opsize=2 & byte=0x0f; byte=0x78; rm64 & Reg64 ... { rm64 = vmread(Reg64); } +:VMREAD rm64, Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0f; byte=0x78; rm64 & Reg64 ... { rm64 = vmread(Reg64); } @endif :VMWRITE Reg32, rm32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0x79; rm32 & Reg32 ... & check_Reg32_dest ... { vmwrite(rm32,Reg32); build check_Reg32_dest; } @ifdef IA64 -:VMWRITE Reg64, rm64 is vexMode=0 & opsize=2 & byte=0x0f; byte=0x79; rm64 & Reg64 ... { vmwrite(rm64,Reg64); } +:VMWRITE Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0f; byte=0x79; rm64 & Reg64 ... { vmwrite(rm64,Reg64); } @endif :VMXOFF is vexMode=0 & byte=0x0f; byte=0x01; byte=0xc4 { vmxoff(); } # NB: this opcode is incorrect in the 2005 edition of the Intel manual. Opcode below is taken from the 2008 version. @@ -3917,11 +3913,11 @@ define pcodeop invalidInstructionException; @ifdef IA64 define pcodeop writefsbase; :WRFSBASE r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=2 & r32 { tmp:8 = zext(r32); writefsbase(tmp); } -:WRFSBASE r64 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=2 & r64 { writefsbase(r64); } +:WRFSBASE r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=2 & r64 { writefsbase(r64); } define pcodeop writegsbase; :WRGSBASE r32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=3 & r32 { tmp:8 = zext(r32); writegsbase(tmp); } -:WRGSBASE r64 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=3 & r64 { writegsbase(r64); } +:WRGSBASE r64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0f; byte=0xae; reg_opcode=3 & r64 { writegsbase(r64); } @endif define pcodeop wrpkru; @@ -3934,7 +3930,7 @@ define pcodeop wrmsr; :XADD rm16,Reg16 is vexMode=0 & opsize=0 & byte=0x0F; byte=0xC1; rm16 & Reg16 ... { addflags(rm16,Reg16); local tmp = rm16 + Reg16; Reg16 = rm16; rm16 = tmp; resultflags(tmp); } :XADD rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x0F; byte=0xC1; rm32 & check_rm32_dest ... & Reg32 ... & check_Reg32_dest ... { addflags(rm32,Reg32); local tmp = rm32 + Reg32; Reg32 = rm32; rm32 = tmp; build check_rm32_dest; build check_Reg32_dest; resultflags(tmp); } @ifdef IA64 -:XADD rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x0F; byte=0xC1; rm64 & Reg64 ... { addflags(rm64,Reg64); local tmp = rm64 + Reg64; Reg64 = rm64; rm64 = tmp; resultflags(tmp); } +:XADD rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x0F; byte=0xC1; rm64 & Reg64 ... { addflags(rm64,Reg64); local tmp = rm64 + Reg64; Reg64 = rm64; rm64 = tmp; resultflags(tmp); } @endif define pcodeop xabort; @@ -3952,50 +3948,50 @@ define pcodeop xend; :XCHG AX,Rmr16 is vexMode=0 & opsize=0 & row = 9 & page = 0 & AX & Rmr16 { local tmp = AX; AX = Rmr16; Rmr16 = tmp; } :XCHG EAX,Rmr32 is vexMode=0 & opsize=1 & row = 9 & page = 0 & EAX & check_EAX_dest & Rmr32 & check_Rmr32_dest { local tmp = EAX; EAX = Rmr32; build check_EAX_dest; Rmr32 = tmp; build check_Rmr32_dest; } @ifdef IA64 -:XCHG RAX,Rmr64 is vexMode=0 & opsize=2 & row = 9 & page = 0 & RAX & Rmr64 { local tmp = RAX; RAX = Rmr64; Rmr64 = tmp; } +:XCHG RAX,Rmr64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & row = 9 & page = 0 & RAX & Rmr64 { local tmp = RAX; RAX = Rmr64; Rmr64 = tmp; } @endif :XCHG rm8,Reg8 is vexMode=0 & byte=0x86; rm8 & Reg8 ... { local tmp = rm8; rm8 = Reg8; Reg8 = tmp; } :XCHG rm16,Reg16 is vexMode=0 & opsize=0 & byte=0x87; rm16 & Reg16 ... { local tmp = rm16; rm16 = Reg16; Reg16 = tmp; } :XCHG rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x87; rm32 & check_rm32_dest ... & Reg32 ... & check_Reg32_dest ... { local tmp = rm32; rm32 = Reg32; build check_rm32_dest; Reg32 = tmp; build check_Reg32_dest;} @ifdef IA64 -:XCHG rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x87; rm64 & Reg64 ... { local tmp = rm64; rm64 = Reg64; Reg64 = tmp; } +:XCHG rm64,Reg64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x87; rm64 & Reg64 ... { local tmp = rm64; rm64 = Reg64; Reg64 = tmp; } @endif :XLAT seg16^BX is vexMode=0 & addrsize=0 & seg16 & byte=0xd7; BX { tmp:$(SIZE)= 0; ptr2(tmp,BX+zext(AL)); AL = *tmp; } :XLAT segWide^EBX is vexMode=0 & addrsize=1 & segWide & byte=0xd7; EBX { tmp:$(SIZE)= 0; ptr4(tmp,EBX+zext(AL)); AL = *tmp; } @ifdef IA64 -:XLAT segWide^RBX is vexMode=0 & addrsize=2 & segWide & byte=0xd7; RBX { tmp:$(SIZE)= 0; ptr8(tmp,RBX+zext(AL)); AL = *tmp; } +:XLAT segWide^RBX is $(LONGMODE_ON) & vexMode=0 & addrsize=2 & segWide & byte=0xd7; RBX { tmp:$(SIZE)= 0; ptr8(tmp,RBX+zext(AL)); AL = *tmp; } @endif :XOR AL,imm8 is vexMode=0 & byte=0x34; AL & imm8 { logicalflags(); AL = AL ^ imm8; resultflags( AL); } :XOR AX,imm16 is vexMode=0 & opsize=0 & byte=0x35; AX & imm16 { logicalflags(); AX = AX ^ imm16; resultflags( AX); } :XOR EAX,imm32 is vexMode=0 & opsize=1 & byte=0x35; EAX & imm32 & check_EAX_dest { logicalflags(); EAX = EAX ^ imm32; build check_EAX_dest; resultflags( EAX);} @ifdef IA64 -:XOR RAX,simm32 is vexMode=0 & opsize=2 & byte=0x35; RAX & simm32 { logicalflags(); RAX = RAX ^ simm32; resultflags( RAX); } +:XOR RAX,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x35; RAX & simm32 { logicalflags(); RAX = RAX ^ simm32; resultflags( RAX); } @endif :XOR spec_rm8,imm8 is vexMode=0 & (byte=0x80 | byte=0x82); spec_rm8 & reg_opcode=6 ...; imm8 { logicalflags(); spec_rm8 = spec_rm8 ^ imm8; resultflags( spec_rm8); } :XOR spec_rm16,imm16 is vexMode=0 & opsize=0 & byte=0x81; spec_rm16 & reg_opcode=6 ...; imm16 { logicalflags(); spec_rm16 = spec_rm16 ^ imm16; resultflags( spec_rm16); } :XOR spec_rm32,imm32 is vexMode=0 & opsize=1 & byte=0x81; spec_rm32 & check_rm32_dest ... & reg_opcode=6 ...; imm32 { logicalflags(); spec_rm32 = spec_rm32 ^ imm32; build check_rm32_dest; resultflags( spec_rm32); } @ifdef IA64 -:XOR spec_rm64,simm32 is vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=6 ...; simm32 { logicalflags(); spec_rm64 = spec_rm64 ^ simm32; resultflags( spec_rm64); } +:XOR spec_rm64,simm32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x81; spec_rm64 & reg_opcode=6 ...; simm32 { logicalflags(); spec_rm64 = spec_rm64 ^ simm32; resultflags( spec_rm64); } @endif :XOR spec_rm16,usimm8_16 is vexMode=0 & opsize=0 & byte=0x83; spec_rm16 & reg_opcode=6 ...; usimm8_16 { logicalflags(); spec_rm16 = spec_rm16 ^ usimm8_16; resultflags( spec_rm16); } :XOR spec_rm32,usimm8_32 is vexMode=0 & opsize=1 & byte=0x83; spec_rm32 & check_rm32_dest ... & reg_opcode=6 ...; usimm8_32 { logicalflags(); spec_rm32 = spec_rm32 ^ usimm8_32; build check_rm32_dest; resultflags( spec_rm32); } @ifdef IA64 -:XOR spec_rm64,usimm8_64 is vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=6 ...; usimm8_64 { logicalflags(); spec_rm64 = spec_rm64 ^ usimm8_64; resultflags( spec_rm64); } +:XOR spec_rm64,usimm8_64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & byte=0x83; spec_rm64 & reg_opcode=6 ...; usimm8_64 { logicalflags(); spec_rm64 = spec_rm64 ^ usimm8_64; resultflags( spec_rm64); } @endif :XOR rm8,Reg8 is vexMode=0 & byte=0x30; rm8 & Reg8 ... { logicalflags(); rm8 = rm8 ^ Reg8; resultflags( rm8); } :XOR rm16,Reg16 is vexMode=0 & opsize=0 & byte=0x31; rm16 & Reg16 ... { logicalflags(); rm16 = rm16 ^ Reg16; resultflags( rm16); } :XOR rm32,Reg32 is vexMode=0 & opsize=1 & byte=0x31; rm32 & check_rm32_dest ... & Reg32 ... { logicalflags(); rm32 = rm32 ^ Reg32; build check_rm32_dest; resultflags( rm32); } @ifdef IA64 -:XOR rm64,Reg64 is vexMode=0 & opsize=2 & byte=0x31; rm64 & Reg64 ... { logicalflags(); rm64 = rm64 ^ Reg64; resultflags( rm64); } +:XOR rm64,Reg64 is vexMode=0 & $(LONGMODE_ON) & opsize=2 & byte=0x31; rm64 & Reg64 ... { logicalflags(); rm64 = rm64 ^ Reg64; resultflags( rm64); } @endif :XOR Reg8,rm8 is vexMode=0 & byte=0x32; rm8 & Reg8 ... { logicalflags(); Reg8 = Reg8 ^ rm8; resultflags( Reg8); } :XOR Reg16,rm16 is vexMode=0 & opsize=0 & byte=0x33; rm16 & Reg16 ... { logicalflags(); Reg16 = Reg16 ^ rm16; resultflags(Reg16); } :XOR Reg32,rm32 is vexMode=0 & opsize=1 & byte=0x33; rm32 & Reg32 ... & check_Reg32_dest ... { logicalflags(); Reg32 = Reg32 ^ rm32; build check_Reg32_dest; resultflags(Reg32); } @ifdef IA64 -:XOR Reg64,rm64 is vexMode=0 & opsize=2 & byte=0x33; rm64 & Reg64 ... { logicalflags(); Reg64 = Reg64 ^ rm64; resultflags(Reg64); } +:XOR Reg64,rm64 is vexMode=0 & $(LONGMODE_ON) & opsize=2 & byte=0x33; rm64 & Reg64 ... { logicalflags(); Reg64 = Reg64 ^ rm64; resultflags(Reg64); } @endif :XGETBV is vexMode=0 & byte=0x0F; byte=0x01; byte=0xD0 { local tmp = XCR0 >> 32; EDX = tmp:4; EAX = XCR0:4; } @@ -4016,32 +4012,32 @@ define pcodeop xrstors64; :XRSTOR Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xrstor(Mem, tmp); } @ifdef IA64 -:XRSTOR64 Mem is vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xrstor64(Mem, tmp); } +:XRSTOR64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xrstor64(Mem, tmp); } @endif :XRSTORS Mem is vexMode=0 & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=3 ) ... & Mem { tmp:4 = 512; xrstors(Mem, tmp); } @ifdef IA64 -:XRSTORS64 Mem is vexMode=0 & $(REX_W) & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=3 ) ... & Mem { tmp:4 = 512; xrstors64(Mem, tmp); } +:XRSTORS64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=3 ) ... & Mem { tmp:4 = 512; xrstors64(Mem, tmp); } @endif :XSAVE Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsave(Mem, tmp); } @ifdef IA64 -:XSAVE64 Mem is vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsave64(Mem, tmp); } +:XSAVE64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsave64(Mem, tmp); } @endif :XSAVEC Mem is vexMode=0 & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsavec(Mem, tmp); } @ifdef IA64 -:XSAVEC64 Mem is vexMode=0 & $(REX_W) & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsavec64(Mem, tmp); } +:XSAVEC64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=4 ) ... & Mem { tmp:4 = 512; xsavec64(Mem, tmp); } @endif :XSAVEOPT Mem is vexMode=0 & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=6 ) ... & Mem { tmp:4 = 512; xsaveopt(Mem, tmp); } @ifdef IA64 -:XSAVEOPT64 Mem is vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=6 ) ... & Mem { tmp:4 = 512; xsaveopt64(Mem, tmp); } +:XSAVEOPT64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xAE; ( mod != 0b11 & reg_opcode=6 ) ... & Mem { tmp:4 = 512; xsaveopt64(Mem, tmp); } @endif :XSAVES Mem is vexMode=0 & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xsaves(Mem, tmp); } @ifdef IA64 -:XSAVES64 Mem is vexMode=0 & $(REX_W) & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xsaves64(Mem, tmp); } +:XSAVES64 Mem is $(LONGMODE_ON) & vexMode=0 & $(REX_W) & byte=0x0F; byte=0xC7; ( mod != 0b11 & reg_opcode=5 ) ... & Mem { tmp:4 = 512; xsaves64(Mem, tmp); } @endif define pcodeop xtest; @@ -5266,7 +5262,7 @@ CMPSS_OPERAND: ", "^imm8 is imm8 { } } @ifdef IA64 -:CVTSD2SI Reg64, m64 is vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2D; Reg64 ... & m64 +:CVTSD2SI Reg64, m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2D; Reg64 ... & m64 { Reg64 = round(m64); } @@ -5293,7 +5289,7 @@ CMPSS_OPERAND: ", "^imm8 is imm8 { } } @ifdef IA64 -:CVTSI2SD XmmReg, rm64 is vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2A; rm64 & XmmReg ... +:CVTSI2SD XmmReg, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2A; rm64 & XmmReg ... { XmmReg[0,64] = int2float(rm64); } @@ -5305,7 +5301,7 @@ CMPSS_OPERAND: ", "^imm8 is imm8 { } } @ifdef IA64 -:CVTSI2SS XmmReg, rm64 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2A; rm64 & XmmReg ... +:CVTSI2SS XmmReg, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2A; rm64 & XmmReg ... { XmmReg[0,32] = int2float(rm64); } @@ -5332,7 +5328,7 @@ CMPSS_OPERAND: ", "^imm8 is imm8 { } } @ifdef IA64 -:CVTSS2SI Reg64, m32 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2D; Reg64 ... & m32 +:CVTSS2SI Reg64, m32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2D; Reg64 ... & m32 { Reg64 = trunc(round(m32)); } @@ -5418,7 +5414,7 @@ CMPSS_OPERAND: ", "^imm8 is imm8 { } } @ifdef IA64 -:CVTTSD2SI Reg64, m64 is vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2C; Reg64 ... & m64 +:CVTTSD2SI Reg64, m64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & byte=0x0F; byte=0x2C; Reg64 ... & m64 { Reg64 = trunc(m64); } @@ -5440,7 +5436,7 @@ CMPSS_OPERAND: ", "^imm8 is imm8 { } } @ifdef IA64 -:CVTTSS2SI Reg64, m32 is vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2C; Reg64 ... & m32 +:CVTTSS2SI Reg64, m32 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & byte=0x0F; byte=0x2C; Reg64 ... & m32 { Reg64 = trunc(m32); } @@ -5678,10 +5674,10 @@ define pcodeop minps; :MOVD XmmReg, rm32 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x6E; rm32 & XmmReg ... { XmmReg = zext(rm32); } :MOVD rm32, XmmReg is vexMode=0 & $(PRE_66) & rexWprefix=0 & byte=0x0F; byte=0x7E; rm32 & check_rm32_dest ... & XmmReg ... { rm32 = XmmReg(0); build check_rm32_dest; } @ifdef IA64 -:MOVQ mmxreg, rm64 is vexMode=0 & opsize=2 & mandover=0 & byte=0x0F; byte=0x6E; rm64 & mmxreg ... { mmxreg = rm64; } -:MOVQ rm64, mmxreg is vexMode=0 & opsize=2 & mandover=0 & byte=0x0F; byte=0x7E; rm64 & mmxreg ... { rm64 = mmxreg; } -:MOVQ XmmReg, rm64 is vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x6E; rm64 & XmmReg ... { XmmReg = zext(rm64); } -:MOVQ rm64, XmmReg is vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x7E; rm64 & XmmReg ... { rm64 = XmmReg(0); } +:MOVQ mmxreg, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0x0F; byte=0x6E; rm64 & mmxreg ... { mmxreg = rm64; } +:MOVQ rm64, mmxreg is $(LONGMODE_ON) & vexMode=0 & opsize=2 & mandover=0 & byte=0x0F; byte=0x7E; rm64 & mmxreg ... { rm64 = mmxreg; } +:MOVQ XmmReg, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x6E; rm64 & XmmReg ... { XmmReg = zext(rm64); } +:MOVQ rm64, XmmReg is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_66) & byte=0x0F; byte=0x7E; rm64 & XmmReg ... { rm64 = XmmReg(0); } @endif :MOVDDUP XmmReg, m64 is vexMode=0 & $(PRE_F2) & byte=0x0F; byte=0x12; m64 & XmmReg ... @@ -8470,12 +8466,12 @@ define pcodeop pinsrd; @ifdef IA64 define pcodeop pinsrq; -:PINSRQ XmmReg, rm64, imm8 is vexMode=0 & bit64=1 & $(PRE_66) & $(REX_W) & byte=0x0F; byte=0x3A; byte=0x22; XmmReg ... & rm64; imm8 { XmmReg = pinsrq(XmmReg, rm64, imm8:8); } +:PINSRQ XmmReg, rm64, imm8 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & $(REX_W) & byte=0x0F; byte=0x3A; byte=0x22; XmmReg ... & rm64; imm8 { XmmReg = pinsrq(XmmReg, rm64, imm8:8); } @endif define pcodeop extractps; @ifdef IA64 -:EXTRACTPS rm64, XmmReg, imm8 is vexMode=0 & bit64=1 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x17; XmmReg ... & rm64; imm8 { rm64 = extractps(XmmReg, imm8:8); } +:EXTRACTPS rm64, XmmReg, imm8 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x17; XmmReg ... & rm64; imm8 { rm64 = extractps(XmmReg, imm8:8); } @endif :EXTRACTPS rm32, XmmReg, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x3A; byte=0x17; XmmReg ... & rm32 & check_rm32_dest ...; imm8 { rm32 = extractps(XmmReg, imm8:8); build check_rm32_dest; } @@ -8487,7 +8483,7 @@ define pcodeop pextrd; @ifdef IA64 define pcodeop pextrq; -:PEXTRQ rm64, XmmReg, imm8 is vexMode=0 & bit64=1 & $(PRE_66) & $(REX_W) & byte=0x0F; byte=0x3A; byte=0x16; XmmReg ... & rm64; imm8 { rm64 = pextrq(XmmReg, imm8:8); } +:PEXTRQ rm64, XmmReg, imm8 is $(LONGMODE_ON) & vexMode=0 & bit64=1 & $(PRE_66) & $(REX_W) & byte=0x0F; byte=0x3A; byte=0x16; XmmReg ... & rm64; imm8 { rm64 = pextrq(XmmReg, imm8:8); } @endif define pcodeop pmovsxbw; @@ -8588,8 +8584,8 @@ define pcodeop crc32; :CRC32 Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F2) & byte=0x0F; byte=0x38; byte=0xF1; Reg32 ... & check_Reg32_dest ... & rm32 { Reg32 = crc32(Reg32, rm32); build check_Reg32_dest; } @ifdef IA64 :CRC32 Reg32, rm8 is vexMode=0 & opsize=1 & $(PRE_F2) & $(REX) & byte=0x0F; byte=0x38; byte=0xF0; Reg32 ... & check_Reg32_dest ... & rm8 { Reg32 = crc32(Reg32, rm8); build check_Reg32_dest; } -:CRC32 Reg64, rm8 is vexMode=0 & opsize=2 & $(PRE_F2) & $(REX_W) & byte=0x0F; byte=0x38; byte=0xF0; Reg64 ... & rm8 { Reg64 = crc32(Reg64, rm8); } -:CRC32 Reg64, rm64 is vexMode=0 & opsize=2 & $(PRE_F2) & $(REX_W) & byte=0x0F; byte=0x38; byte=0xF1; Reg64 ... & rm64 { Reg64 = crc32(Reg64, rm64); } +:CRC32 Reg64, rm8 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & $(REX_W) & byte=0x0F; byte=0x38; byte=0xF0; Reg64 ... & rm8 { Reg64 = crc32(Reg64, rm8); } +:CRC32 Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F2) & $(REX_W) & byte=0x0F; byte=0x38; byte=0xF1; Reg64 ... & rm64 { Reg64 = crc32(Reg64, rm64); } @endif define pcodeop pcmpestri; @@ -8616,7 +8612,7 @@ define pcodeop popcnt; :POPCNT Reg16, rm16 is vexMode=0 & opsize=0 & $(PRE_F3) & byte=0x0F; byte=0xB8; Reg16 ... & rm16 { Reg16 = popcnt(rm16); } :POPCNT Reg32, rm32 is vexMode=0 & opsize=1 & $(PRE_F3) & byte=0x0F; byte=0xB8; Reg32 ... & check_Reg32_dest ... & rm32 { Reg32 = popcnt(rm32); build check_Reg32_dest; } @ifdef IA64 -:POPCNT Reg64, rm64 is vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xB8; Reg64 ... & rm64 { Reg64 = popcnt(rm64); } +:POPCNT Reg64, rm64 is $(LONGMODE_ON) & vexMode=0 & opsize=2 & $(PRE_F3) & $(REX_W) & byte=0x0F; byte=0xB8; Reg64 ... & rm64 { Reg64 = popcnt(rm64); } @endif diff --git a/Ghidra/Processors/x86/data/languages/lzcnt.sinc b/Ghidra/Processors/x86/data/languages/lzcnt.sinc index 0a7e8da282..be3861b875 100644 --- a/Ghidra/Processors/x86/data/languages/lzcnt.sinc +++ b/Ghidra/Processors/x86/data/languages/lzcnt.sinc @@ -46,7 +46,7 @@ macro lzcntflags(input, output) { } @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; inputTmp:8 = rm64; diff --git a/Ghidra/Processors/x86/data/languages/mpx.sinc b/Ghidra/Processors/x86/data/languages/mpx.sinc index 9d3ba41971..db600d4809 100644 --- a/Ghidra/Processors/x86/data/languages/mpx.sinc +++ b/Ghidra/Processors/x86/data/languages/mpx.sinc @@ -5,7 +5,6 @@ define pcodeop br_exception; # - if no base register, needs 0 @ifdef IA64 - bndmk_addr64: [Rmr64] is mod=0 & Rmr64 { 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; } @@ -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: [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; } +@endif -@else 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] 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: [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; } -@endif @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 !(Rmr64 < bnd1_lb) goto ; BNDSTATUS = 0x01; @@ -58,7 +56,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(Mem < bnd1_lb) goto ; BNDSTATUS = 0x01; @@ -66,7 +64,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(Rmr64 > ~bnd1_ub) goto ; BNDSTATUS = 0x01; @@ -74,7 +72,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(Mem > ~bnd1_ub) goto ; BNDSTATUS = 0x01; @@ -82,7 +80,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(Rmr64 > bnd1_ub) goto ; BNDSTATUS = 0x01; @@ -90,7 +88,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(Mem > bnd1_ub) goto ; 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 -: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 ); # 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; } -: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 bnd1_lb = bndmk_addr64; 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; } -: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; } -: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; } -: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; } #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 ); # 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; } +@endif - -@else - -:BNDCL bnd1, Rmr32 is vexMode=0 & $(PRE_F3) & byte=0x0F; byte=0x1A; mod=3 & bnd1 & bnd1_lb & Rmr32 { +:BNDCL bnd1, Rmr32 is $(LONGMODE_OFF) & 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 !(zext(Rmr32) < bnd1_lb) goto ; BNDSTATUS = 0x01; @@ -150,7 +146,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(zext(Mem) < bnd1_lb) goto ; BNDSTATUS = 0x01; @@ -158,7 +154,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(zext(Rmr32) > ~bnd1_ub) goto ; BNDSTATUS = 0x01; @@ -166,7 +162,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(zext(Mem) > ~bnd1_ub) goto ; BNDSTATUS = 0x01; @@ -174,7 +170,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(zext(Rmr32) > bnd1_ub) goto ; BNDSTATUS = 0x01; @@ -182,7 +178,7 @@ bndmk_addr32: [Base] is mod=2 & r_m=4; index=4 & Base; imm32=0 { export B } -: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 !(zext(Mem) > bnd1_ub) goto ; 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 -: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 ); # 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); } -: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 bnd1_lb = zext(bndmk_addr32); 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; bnd1_lb = zext(tmp:4); tmp2:4 = tmp(4); 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; } -: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); } -: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; } #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 ); # 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); } - -@endif diff --git a/Ghidra/Processors/x86/data/languages/rdrand.sinc b/Ghidra/Processors/x86/data/languages/rdrand.sinc index 5b68faa7a5..caf3cc1756 100644 --- a/Ghidra/Processors/x86/data/languages/rdrand.sinc +++ b/Ghidra/Processors/x86/data/languages/rdrand.sinc @@ -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 rm32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; (rm32 & reg_opcode=6 ...) { rm32 = rdrand(); CF=rdrandIsValid(); } @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 diff --git a/Ghidra/Processors/x86/data/languages/rdseed.sinc b/Ghidra/Processors/x86/data/languages/rdseed.sinc index 144e56ae19..1718f35d7f 100644 --- a/Ghidra/Processors/x86/data/languages/rdseed.sinc +++ b/Ghidra/Processors/x86/data/languages/rdseed.sinc @@ -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 r32 is vexMode=0 & opsize=1 & byte=0x0f; byte=0xC7; r32 & reg_opcode=7 { r32 = rdseed(); CF=rdseedIsValid(); } @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 diff --git a/Ghidra/Processors/x86/data/languages/x86-64.pspec b/Ghidra/Processors/x86/data/languages/x86-64.pspec index 66d743ff07..315344dc99 100644 --- a/Ghidra/Processors/x86/data/languages/x86-64.pspec +++ b/Ghidra/Processors/x86/data/languages/x86-64.pspec @@ -12,6 +12,7 @@ +