Merge remote-tracking branch 'origin/patch'

Conflicts:
	Ghidra/Framework/SoftwareModeling/src/test/java/ghidra/app/plugin/processors/sleigh/SleighLanguageVolatilityTest.java
This commit is contained in:
Ryan Kurtz 2023-01-20 12:31:22 -05:00
commit 1b9f90e827
4 changed files with 181 additions and 206 deletions

View File

@ -31,6 +31,7 @@ dependencies {
api project(':SoftwareModeling')
// include Base src/test/resources when running decompiler integration tests (uses defaultTools)
integrationTestImplementation project(path: ':Base', configuration: 'testArtifacts')
integrationTestImplementation project(path: ':SoftwareModeling', configuration: 'testArtifacts')
helpPath project(path: ":Base", configuration: 'helpPath')
}

View File

@ -15,28 +15,26 @@
*/
package ghidra.app.plugin.core.decompile;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import ghidra.app.decompiler.DecompInterface;
import ghidra.app.decompiler.DecompileOptions;
import ghidra.app.decompiler.DecompileResults;
import org.junit.*;
import ghidra.app.decompiler.*;
import ghidra.app.plugin.processors.sleigh.SleighLanguageVolatilityTest;
import ghidra.program.database.ProgramBuilder;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressFormatException;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.Program;
import ghidra.program.database.ProgramBuilder;
import ghidra.util.task.TaskMonitor;
public class DecompilerPspecVolatilityTest extends SleighLanguageVolatilityTest {
private Program prog;
private DecompInterface decompiler;
private String functionBytes = "84 ff 02 c0 8d 9a 01 c0 8d 98 85 ff 02 c0 a4 9a 01 c0 a4 98 2f "
+ "b7 86 ff 05 c0 f8 94 90 91 02 01 90 68 04 c0 f8 94 90 91 02 01 9f 77 90 93 02 01"
+ " 2f bf 87 ff 02 c0 a3 9a 01 c0 a3 98 8f 9a 85 e0 8a 95 f1 f7 00 00 8f 98 08";
private String functionBytes =
"84 ff 02 c0 8d 9a 01 c0 8d 98 85 ff 02 c0 a4 9a 01 c0 a4 98 2f " +
"b7 86 ff 05 c0 f8 94 90 91 02 01 90 68 04 c0 f8 94 90 91 02 01 9f 77 90 93 02 01" +
" 2f bf 87 ff 02 c0 a3 9a 01 c0 a3 98 8f 9a 85 e0 8a 95 f1 f7 00 00 8f 98 08";
private int functionLength = 27;
private String addressString = "0x1000";
private String decompilation;
@ -44,39 +42,38 @@ public class DecompilerPspecVolatilityTest extends SleighLanguageVolatilityTest
private String decompilerPORTGNotVolatileString = "DAT_mem_0034 = DAT_mem_0034";
private boolean decompilerPORTFVolatile;
private boolean decompilerPORTGVolatile;
public void setUp(Boolean symbolVolatile, Integer symbolSize, Boolean memoryVolatile, boolean reverse) throws Exception {
public void setUp(Boolean symbolVolatile, Integer symbolSize, Boolean memoryVolatile,
boolean reverse) throws Exception {
super.setUp(symbolVolatile, symbolSize, memoryVolatile, reverse);
ProgramBuilder builder = new ProgramBuilder("test", lang);
builder.setBytes(addressString, functionBytes);
builder.disassemble(addressString, functionLength, false);
builder.createFunction(addressString);
prog = builder.getProgram();
if (decompiler != null) {
decompiler.dispose();
}
decompiler = new DecompInterface();
decompiler.openProgram(prog);
decompilation = getDecompilationString(addressString);
decompilerPORTFVolatile = !decompilation.contains(decompilerPORTFNotVolatileString);
decompilerPORTGVolatile = !decompilation.contains(decompilerPORTGNotVolatileString);
}
private String getDecompilationString(String address) throws AddressFormatException
{
private String getDecompilationString(String address) throws AddressFormatException {
Address addr = prog.getAddressFactory().getDefaultAddressSpace().getAddress(address);
Function func = prog.getListing().getFunctionAt(addr);
DecompileResults decompResults = decompiler.decompileFunction(func,
DecompileOptions.SUGGESTED_DECOMPILE_TIMEOUT_SECS, TaskMonitor.DUMMY);
String decompilation = decompResults.getDecompiledFunction().getC();
return decompilation;
return decompResults.getDecompiledFunction().getC();
}
@After
@ -85,33 +82,33 @@ public class DecompilerPspecVolatilityTest extends SleighLanguageVolatilityTest
decompiler.dispose();
}
}
@Test
public void testDecompileInterfaceReturnsAFunction() throws Exception {
setUp(null, null, false, false);
Assert.assertNotNull(decompilation);
}
@Test
public void testDecompilePORTFSymbolPspecSettings() throws Exception {
setUp(null, null, null, false);
//Decompiler should indicate mem:0x31 is not volatile
Assert.assertFalse(decompilerPORTFVolatile);
setUp(false, null, null, false);
//Decompiler should indicate mem:0x31 is not volatile
Assert.assertFalse(decompilerPORTFVolatile);
setUp(true, null, null, false);
//Decompiler should indicate mem:0x31 is volatile because the symbol element in the language
//pspec file defined the symbol at mem:0x31 to be volatile.
Assert.assertTrue(decompilerPORTFVolatile);
}
@Test
public void testDecompilePORTFMemoryPspecSettings() throws Exception {
setUp(null, null, true, false);
@ -119,51 +116,51 @@ public class DecompilerPspecVolatilityTest extends SleighLanguageVolatilityTest
//Decompiler should indicate mem:0x31 is volatile because the pspec file includes a volatile
//element that defines the memory location that includes 0x31 as volatile.
Assert.assertTrue(decompilerPORTFVolatile);
setUp(null, null, false, false);
//Decompiler should indicate mem:0x31 is not volatile
Assert.assertFalse(decompilerPORTFVolatile);
setUp(null, null, null, false);
//Decompiler should indicate mem:0x31 is not volatile
Assert.assertFalse(decompilerPORTFVolatile);
setUp(false, null, true, false);
//Decompiler should indicate mem:0x31 is not volatile because the pspec file defines the
//symbol element PORTF as not volatile and that takes precedence over the pspec's volatile
//element.
Assert.assertFalse(decompilerPORTFVolatile);
setUp(true, null, true, false);
//Decompiler should indicate mem:0x31 is volatile
Assert.assertTrue(decompilerPORTFVolatile);
setUp(false, null, true, true);
//Decompiler should indicate mem:0x31 is not volatile
Assert.assertFalse(decompilerPORTFVolatile);
}
@Test
public void testDecompilePORFSizeOverwritesPORTG() throws Exception {
setUp(true, 1, null, false);
//Decompiler should indicate mem:0x31 and mem:0x34 are volatile
Assert.assertTrue(decompilerPORTFVolatile);
Assert.assertFalse(decompilerPORTGVolatile);
setUp(false, 4, true, false); //size of 4 addressable units 0x31, 0x32, 0x33 0x34
//Decompiler should indicate mem:0x31 and mem:0x34 are not volatile
Assert.assertFalse(decompilerPORTFVolatile);
Assert.assertFalse(decompilerPORTGVolatile);
setUp(true, 4, null, false);
//Decompiler should indicate mem:0x31 and mem:0x34 are volatile
Assert.assertTrue(decompilerPORTFVolatile);
Assert.assertTrue(decompilerPORTGVolatile);

View File

@ -26,13 +26,13 @@ import ghidra.framework.Application;
import ghidra.program.model.address.Address;
import ghidra.program.model.lang.LanguageID;
public class SleighLanguageVolatilityTest extends AbstractGenericTest{
public class SleighLanguageVolatilityTest extends AbstractGenericTest {
protected SleighLanguage lang;
protected String PORTFAddressString = "mem:0x31";
protected String PORTGAddressString = "mem:0x34";
protected boolean isPORTFVolatile;
protected boolean isPORTGVolatile;
/**
* Constructs a string based on parameters, and uses that as the content of a custom pspec file.
* Parameters effect the volatility of the symbol "PORTF".
@ -43,81 +43,68 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest{
* memory location that includes PORTF.
* @param reverseOrder boolean, reverseOrder refers to the order that 'volatile' and
* 'default_symbols' elements appear in the pspec file.
* @throws Exception if unexpected error occurs
* @returns the data
* @throws Exception if an error occurred
*/
public void setUp(Boolean symbolVolatile, Integer symbolSize, Boolean memoryVolatile, boolean reverseOrder) throws Exception {
public void setUp(Boolean symbolVolatile, Integer symbolSize, Boolean memoryVolatile,
boolean reverseOrder) throws Exception {
//symbolVolatile and symbolSize are in reference to the symbol PORTF. However, setting a
//size that is too large will overwrite other symbols such as PING, DDRG or PORTG.
String defaultSymbolsElement =
" <default_symbols>\r\n"
+ " <symbol name=\"RESET\" address=\"code:0x0000\" entry=\"true\"/>\r\n"
+ " <symbol name=\"INT0\" address=\"code:0x0002\" entry=\"true\"/>\r\n"
+ " <symbol name=\"INT1\" address=\"code:0x0004\" entry=\"true\"/>\r\n"
+ " <symbol name=\"PORTE\" address=\"mem:0x2e\"/>\r\n"
+ " <symbol name=\"PINF\" address=\"mem:0x2f\"/>\r\n"
+ " <symbol name=\"DDRF\" address=\"mem:0x30\"/>\r\n"
+ " <symbol name=\"PORTF\" address=\"mem:0x31\"";
defaultSymbolsElement += symbolVolatile==null ? "" : " volatile=\"" + symbolVolatile.toString() + "\"";
defaultSymbolsElement += symbolSize==null ? "" : " size=\"" + symbolSize.toString() + "\"";
defaultSymbolsElement += " />\r\n"
+ " <symbol name=\"PING\" address=\"mem:0x32\"/>\r\n"
+ " <symbol name=\"DDRG\" address=\"mem:0x33\"/>\r\n"
+ " <symbol name=\"PORTG\" address=\"mem:0x34\"/>\r\n"
+ " <symbol name=\"TIFR0\" address=\"mem:0x35\"/>\r\n"
+ " </default_symbols>\r\n";
String defaultSymbolsElement =
" <default_symbols>\r\n" +
" <symbol name=\"RESET\" address=\"code:0x0000\" entry=\"true\"/>\r\n" +
" <symbol name=\"INT0\" address=\"code:0x0002\" entry=\"true\"/>\r\n" +
" <symbol name=\"INT1\" address=\"code:0x0004\" entry=\"true\"/>\r\n" +
" <symbol name=\"PORTE\" address=\"mem:0x2e\"/>\r\n" +
" <symbol name=\"PINF\" address=\"mem:0x2f\"/>\r\n" +
" <symbol name=\"DDRF\" address=\"mem:0x30\"/>\r\n" +
" <symbol name=\"PORTF\" address=\"mem:0x31\"";
defaultSymbolsElement +=
symbolVolatile == null ? "" : " volatile=\"" + symbolVolatile.toString() + "\"";
defaultSymbolsElement +=
symbolSize == null ? "" : " size=\"" + symbolSize.toString() + "\"";
defaultSymbolsElement += " />\r\n" +
" <symbol name=\"PING\" address=\"mem:0x32\"/>\r\n" +
" <symbol name=\"DDRG\" address=\"mem:0x33\"/>\r\n" +
" <symbol name=\"PORTG\" address=\"mem:0x34\"/>\r\n" +
" <symbol name=\"TIFR0\" address=\"mem:0x35\"/>\r\n" + " </default_symbols>\r\n";
//memoryVolatile null will not set the memory range 0x20 to 0x57 as volatile.
//memoryVolatile true will set the memory range 0x20 to 0x57 to volatile.
//memoryVolatile false will exclude the address of PORTF (0x31) from the volatility setting.
//Example:
// "<range space=\"mem\" first=\"0x20\" last=\"0x30\"/>"
// "<range space=\"mem\" first=\"0x32\" last=\"0x57\"/>"
String volatileElement =
" <volatile outputop=\"write_volatile\" inputop=\"read_volatile\">\r\n";
volatileElement += memoryVolatile == null ? "" :
memoryVolatile ?
"<range space=\"mem\" first=\"0x20\" last=\"0x57\"/>\r\n"
:
"<range space=\"mem\" first=\"0x20\" last=\"0x30\"/>\r\n"
+ "<range space=\"mem\" first=\"0x32\" last=\"0x57\"/>\r\n";
volatileElement += " <range space=\"mem\" first=\"0x60\" last=\"0xff\"/>\r\n"
+ " </volatile>\r\n";
String volatileElement =
" <volatile outputop=\"write_volatile\" inputop=\"read_volatile\">\r\n";
volatileElement += memoryVolatile == null ? ""
: memoryVolatile ? "<range space=\"mem\" first=\"0x20\" last=\"0x57\"/>\r\n"
: "<range space=\"mem\" first=\"0x20\" last=\"0x30\"/>\r\n" +
"<range space=\"mem\" first=\"0x32\" last=\"0x57\"/>\r\n";
volatileElement +=
" <range space=\"mem\" first=\"0x60\" last=\"0xff\"/>\r\n" + " </volatile>\r\n";
//This variable represents the content of a pspec file.
//The original pspec file this is based on is the avr8 atmega256.pspec.
String pspecContentString =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
+ "\r\n"
+ "<processor_spec>\r\n"
+ "\r\n"
+ " <programcounter register=\"PC\"/> \r\n"
+ " <data_space space=\"mem\"/>\r\n";
String pspecContentString =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + "\r\n" + "<processor_spec>\r\n" +
"\r\n" + " <programcounter register=\"PC\"/> \r\n" +
" <data_space space=\"mem\"/>\r\n";
pspecContentString += reverseOrder ? volatileElement : defaultSymbolsElement;
pspecContentString += " \r\n"
+ " <context_data>\r\n"
+ " <tracked_set space=\"code\">\r\n"
+ " <set name=\"R1\" val=\"0\"/>\r\n"
+ " </tracked_set>\r\n"
+ " </context_data>\r\n"
+ " \r\n";
pspecContentString += " \r\n" + " <context_data>\r\n" +
" <tracked_set space=\"code\">\r\n" + " <set name=\"R1\" val=\"0\"/>\r\n" +
" </tracked_set>\r\n" + " </context_data>\r\n" + " \r\n";
pspecContentString += reverseOrder ? defaultSymbolsElement : volatileElement;
pspecContentString += "\r\n"
+ " <default_memory_blocks>\r\n"
+ " <memory_block name=\"regalias\" start_address=\"mem:0x00\" length=\"0x20\" initialized=\"false\"/>\r\n"
+ " <memory_block name=\"iospace\" start_address=\"mem:0x20\" length=\"0x1e0\" initialized=\"false\"/>\r\n"
+ " <memory_block name=\"sram\" start_address=\"mem:0x200\" length=\"0x4000\" initialized=\"false\"/>\r\n"
+ " <memory_block name=\"codebyte\" start_address=\"codebyte:0x0\" length=\"0x40000\" byte_mapped_address=\"code:0x0\"/>\r\n"
+ " </default_memory_blocks>\r\n"
+ "\r\n"
+ "\r\n"
+ "</processor_spec>\r\n"
+ "";
pspecContentString += "\r\n" + " <default_memory_blocks>\r\n" +
" <memory_block name=\"regalias\" start_address=\"mem:0x00\" length=\"0x20\" initialized=\"false\"/>\r\n" +
" <memory_block name=\"iospace\" start_address=\"mem:0x20\" length=\"0x1e0\" initialized=\"false\"/>\r\n" +
" <memory_block name=\"sram\" start_address=\"mem:0x200\" length=\"0x4000\" initialized=\"false\"/>\r\n" +
" <memory_block name=\"codebyte\" start_address=\"codebyte:0x0\" length=\"0x40000\" byte_mapped_address=\"code:0x0\"/>\r\n" +
" </default_memory_blocks>\r\n" + "\r\n" + "\r\n" + "</processor_spec>\r\n" + "";
String languageIDString = "avr8:LE:16:atmega256Test";
LanguageID langId = new LanguageID(languageIDString);
ResourceFile pspecFile = createCustomPspecFile("atmega256", pspecContentString);
ResourceFile ldefFile = createTempLdefsFile("avr8", pspecFile);
SleighLanguageProvider provider = new SleighLanguageProvider(ldefFile);
@ -125,93 +112,93 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest{
Address PORTFAddress = lang.getAddressFactory().getAddress(PORTFAddressString);
Address PORTGAddress = lang.getAddressFactory().getAddress(PORTGAddressString);
isPORTFVolatile = lang.isVolatile(PORTFAddress);
isPORTGVolatile = lang.isVolatile(PORTGAddress);
}
@Test
public void testPORTFWithSymbolVolatility() throws Exception {
setUp(null, null, null, false);
Assert.assertFalse(isPORTFVolatile);
setUp(false, null, null, false);
Assert.assertFalse(isPORTFVolatile);
setUp(true, null, null, false);
Assert.assertTrue(isPORTFVolatile);
}
@Test
public void testPORTFWithSize() throws Exception {
setUp(null, 1, null, false);
Assert.assertFalse(isPORTFVolatile);
Assert.assertFalse(isPORTGVolatile);
setUp(false, 1, null, false);
Assert.assertFalse(isPORTFVolatile);
Assert.assertFalse(isPORTGVolatile);
setUp(true, 1, null, false);
Assert.assertTrue(isPORTFVolatile);
Assert.assertFalse(isPORTGVolatile);
setUp(null, 4, null, false);
Assert.assertFalse(isPORTFVolatile);
Assert.assertFalse(isPORTGVolatile);
setUp(false, 4, null, false);
Assert.assertFalse(isPORTFVolatile);
Assert.assertFalse(isPORTGVolatile);
setUp(true, 4, null, false); // setting portf to size 4 overwrites portg as well
Assert.assertTrue(isPORTFVolatile);
Assert.assertTrue(isPORTGVolatile);
}
@Test
public void testPORTFNoSizeOrSymbolVolatility() throws Exception {
setUp(null, null, null, false);
Assert.assertFalse(isPORTFVolatile);
setUp(null, null, false, false);
Assert.assertFalse(isPORTFVolatile);
setUp(null, null, true, false);
Assert.assertTrue(isPORTFVolatile);
}
@Test
public void testPORTFNoSize() throws Exception {
setUp(true, null, true, false);
Assert.assertTrue(isPORTFVolatile);
setUp(false, null, true, false);
Assert.assertFalse(isPORTFVolatile);
setUp(true, null, false, false);
Assert.assertTrue(isPORTFVolatile);
setUp(false, null, false, false);
Assert.assertFalse(isPORTFVolatile);
}
@Test
public void testReverseSettingPORTFVolatile() throws Exception {
setUp(false, null, null, true);
@ -219,12 +206,12 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest{
setUp(true, null, null, true);
Assert.assertTrue(isPORTFVolatile);
}
private ResourceFile createTempLdefsFile(String name, ResourceFile pspecFile) {
String pspecFilename = pspecFile.getName();
return createCustomLdefFile("avr8", pspecFilename);
}
public ResourceFile createCustomPspecFile(String name, String content) {
File newPspecFile = null;
try {
@ -232,26 +219,25 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest{
BufferedWriter bw = new BufferedWriter(new FileWriter(newPspecFile));
bw.write(content);
bw.close();
}
catch(IOException e){
catch (IOException e) {
System.err.println("Error creating test pspec file.");
}
newPspecFile.deleteOnExit();
return new ResourceFile(newPspecFile);
}
public ResourceFile createCustomLdefFile(String name, String pspecFilename) {
Iterable<ResourceFile> files = Application.findFilesByExtensionInApplication(".ldefs");
ResourceFile originalLdefFile = null;
for (ResourceFile file : files) {
if (file.getName().equals(name + ".ldefs"))
{
if (file.getName().equals(name + ".ldefs")) {
originalLdefFile = file;
break;
}
}
try {
File editedPspecFile = File.createTempFile(name, ".ldefs");
BufferedReader br = new BufferedReader(new FileReader(originalLdefFile.getFile(false)));
@ -260,14 +246,12 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest{
while ((s = br.readLine()) != null) {
//if the string is defining a filename, edit that line
String originalPspecFilename = "atmega256.pspec";
if ( s.contains(originalPspecFilename) )
{
if (s.contains(originalPspecFilename)) {
s = s.replace(originalPspecFilename, pspecFilename);
}
if (s.contains("avr8:LE:16:atmega256"))
{
if (s.contains("avr8:LE:16:atmega256")) {
s = s.replace("avr8:LE:16:atmega256", "avr8:LE:16:atmega256Test");
}
bw.write(s);
@ -278,11 +262,11 @@ public class SleighLanguageVolatilityTest extends AbstractGenericTest{
editedPspecFile.deleteOnExit();
return new ResourceFile(editedPspecFile);
}
catch(IOException e) {
catch (IOException e) {
System.err.println("Error creating test pspec file.");
}
return null;
}
}

View File

@ -7180,42 +7180,39 @@ define pcodeop pshufb;
:PSHUFB XmmReg1, XmmReg2 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x38; byte=0x00; xmmmod = 3 & XmmReg1 & XmmReg2 { XmmReg1=pshufb(XmmReg1,XmmReg2); }
# determine the total shift required by the bit fields in a shuffle opcode
Order0: order0 is imm8 [ order0 = (( imm8 & 0x3) << 5); ] { export *[const]:1 order0; }
Order1: order1 is imm8 [ order1 = (((imm8 >> 2) & 0x3) << 5); ] { export *[const]:1 order1; }
Order2: order2 is imm8 [ order2 = (((imm8 >> 4) & 0x3) << 5); ] { export *[const]:1 order2; }
Order3: order3 is imm8 [ order3 = (((imm8 >> 6) & 0x3) << 5); ] { export *[const]:1 order3; }
Order0: order0 is imm8 [ order0 = ( imm8 & 0x3); ] { export *[const]:1 order0; }
Order1: order1 is imm8 [ order1 = ((imm8 >> 2) & 0x3); ] { export *[const]:1 order1; }
Order2: order2 is imm8 [ order2 = ((imm8 >> 4) & 0x3); ] { export *[const]:1 order2; }
Order3: order3 is imm8 [ order3 = ((imm8 >> 6) & 0x3); ] { export *[const]:1 order3; }
macro shuffle_4(dest,ord,c0,c1,c2,c3){
dest = zext(ord == 0) * c0 + zext(ord == 1) * c1 + zext(ord == 2) * c2 + zext(ord == 3) * c3;
}
:PSHUFD XmmReg1, m128, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x70; (m128 & XmmReg1 ...); imm8 & Order0 & Order1 & Order2 & Order3
{
shifted:16 = m128 >> Order0;
XmmReg1[0,32] = shifted:4;
shifted = m128 >> Order1;
XmmReg1[32,32] = shifted:4;
local c0 = m128[0,32];
local c1 = m128[32,32];
local c2 = m128[64,32];
local c3 = m128[96,32];
shifted = m128 >> Order2;
XmmReg1[64,32] = shifted:4;
shifted = m128 >> Order3;
XmmReg1[96,32] = shifted:4;
shuffle_4(XmmReg1[0,32],Order0,c0,c1,c2,c3);
shuffle_4(XmmReg1[32,32],Order1,c0,c1,c2,c3);
shuffle_4(XmmReg1[64,32],Order2,c0,c1,c2,c3);
shuffle_4(XmmReg1[96,32],Order3,c0,c1,c2,c3);
}
:PSHUFD XmmReg1, XmmReg2, imm8 is vexMode=0 & $(PRE_66) & byte=0x0F; byte=0x70; xmmmod=3 & XmmReg1 & XmmReg2 ; imm8 & Order0 & Order1 & Order2 & Order3
{
#in case XmmReg1 and XmmReg2 are the same register
local original_XmmReg2:16 = XmmReg2;
shifted:16 = original_XmmReg2 >> Order0;
XmmReg1[0,32] = shifted:4;
shifted = original_XmmReg2 >> Order1;
XmmReg1[32,32] = shifted:4;
local c0 = XmmReg2[0,32];
local c1 = XmmReg2[32,32];
local c2 = XmmReg2[64,32];
local c3 = XmmReg2[96,32];
shifted = original_XmmReg2 >> Order2;
XmmReg1[64,32] = shifted:4;
shifted = original_XmmReg2 >> Order3;
XmmReg1[96,32] = shifted:4;
shuffle_4(XmmReg1[0,32],Order0,c0,c1,c2,c3);
shuffle_4(XmmReg1[32,32],Order1,c0,c1,c2,c3);
shuffle_4(XmmReg1[64,32],Order2,c0,c1,c2,c3);
shuffle_4(XmmReg1[96,32],Order3,c0,c1,c2,c3);
}
define pcodeop pshufhw;
@ -8048,42 +8045,38 @@ define pcodeop shufpd;
:SHUFPS XmmReg, m128, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xC6; (m128 & XmmReg ...); imm8 & Order0 & Order1 & Order2 & Order3
{
shifted:16 = XmmReg >> Order0;
tempA:4 = shifted:4;
shifted = XmmReg >> Order1;
tempB:4 = shifted:4;
local m128_c0 = m128[0,32];
local m128_c1 = m128[32,32];
local m128_c2 = m128[64,32];
local m128_c3 = m128[96,32];
shifted = m128 >> Order2;
tempC:4 = shifted:4;
local xmm_c0 = XmmReg[0,32];
local xmm_c1 = XmmReg[32,32];
local xmm_c2 = XmmReg[64,32];
local xmm_c3 = XmmReg[96,32];
shifted = m128 >> Order3;
tempD:4 = shifted:4;
XmmReg[0,32] = tempA;
XmmReg[32,32] = tempB;
XmmReg[64,32] = tempC;
XmmReg[96,32] = tempD;
shuffle_4(XmmReg[0,32],Order0,xmm_c0,xmm_c1,xmm_c2,xmm_c3);
shuffle_4(XmmReg[32,32],Order1,xmm_c0,xmm_c1,xmm_c2,xmm_c3);
shuffle_4(XmmReg[64,32],Order2,m128_c0,m128_c1,m128_c2,m128_c3);
shuffle_4(XmmReg[96,32],Order3,m128_c0,m128_c1,m128_c2,m128_c3);
}
:SHUFPS XmmReg1, XmmReg2, imm8 is vexMode=0 & mandover=0 & byte=0x0F; byte=0xC6; xmmmod=3 & XmmReg1 & XmmReg2; imm8 & Order0 & Order1 & Order2 & Order3
{
shifted:16 = XmmReg1 >> Order0;
tempA:4 = shifted:4;
shifted = XmmReg1 >> Order1;
tempB:4 = shifted:4;
local xmm1_c0 = XmmReg1[0,32];
local xmm1_c1 = XmmReg1[32,32];
local xmm1_c2 = XmmReg1[64,32];
local xmm1_c3 = XmmReg1[96,32];
shifted = XmmReg2 >> Order2;
tempC:4 = shifted:4;
local xmm2_c0 = XmmReg2[0,32];
local xmm2_c1 = XmmReg2[32,32];
local xmm2_c2 = XmmReg2[64,32];
local xmm2_c3 = XmmReg2[96,32];
shifted = XmmReg2 >> Order3;
tempD:4 = shifted:4;
XmmReg1[0,32] = tempA;
XmmReg1[32,32] = tempB;
XmmReg1[64,32] = tempC;
XmmReg1[96,32] = tempD;
shuffle_4(XmmReg1[0,32],Order0,xmm1_c0,xmm1_c1,xmm1_c2,xmm1_c3);
shuffle_4(XmmReg1[32,32],Order1,xmm1_c0,xmm1_c1,xmm1_c2,xmm1_c3);
shuffle_4(XmmReg1[64,32],Order2,xmm2_c0,xmm2_c1,xmm2_c2,xmm2_c3);
shuffle_4(XmmReg1[96,32],Order3,xmm2_c0,xmm2_c1,xmm2_c2,xmm2_c3);
}
define pcodeop sqrtpd;