mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-26 14:12:17 +00:00
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:
commit
1b9f90e827
@ -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')
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user