Merge remote-tracking branch 'origin/GP-343_AARCH64neon' into Ghidra_9.2

This commit is contained in:
ghidra1 2020-10-29 18:55:15 -04:00
commit d3950946e6
23 changed files with 9618 additions and 38765 deletions

View File

@ -1987,7 +1987,7 @@ bool SleighCompile::undefinePreprocValue(const string &nm)
// Functions needed by the parser
TokenSymbol *SleighCompile::defineToken(string *name,uintb *sz)
TokenSymbol *SleighCompile::defineToken(string *name,uintb *sz,int4 endian)
{
uint4 size = *sz;
@ -1998,7 +1998,12 @@ TokenSymbol *SleighCompile::defineToken(string *name,uintb *sz)
}
else
size = size/8;
Token *newtoken = new Token(*name,size,isBigEndian(),tokentable.size());
bool isBig;
if (endian ==0)
isBig = isBigEndian();
else
isBig = (endian > 0);
Token *newtoken = new Token(*name,size,isBig,tokentable.size());
tokentable.push_back(newtoken);
delete name;
TokenSymbol *res = new TokenSymbol(newtoken);

View File

@ -261,7 +261,7 @@ public:
bool undefinePreprocValue(const string &nm);
// Parser functions
TokenSymbol *defineToken(string *name,uintb *sz);
TokenSymbol *defineToken(string *name,uintb *sz,int4 endian);
void addTokenField(TokenSymbol *sym,FieldQuality *qual);
bool addContextField(VarnodeSymbol *sym,FieldQuality *qual);
void newSpace(SpaceQuality *qual);

View File

@ -181,7 +181,9 @@ aligndef: DEFINE_KEY ALIGN_KEY '=' INTEGER ';' { slgh->setAlignment(*$4); delete
;
tokendef: tokenprop ';' {}
;
tokenprop: DEFINE_KEY TOKEN_KEY STRING '(' INTEGER ')' { $$ = slgh->defineToken($3,$5); }
tokenprop: DEFINE_KEY TOKEN_KEY STRING '(' INTEGER ')' { $$ = slgh->defineToken($3,$5,0); }
| DEFINE_KEY TOKEN_KEY STRING '(' INTEGER ')' ENDIAN_KEY '=' LITTLE_KEY { $$ = slgh->defineToken($3,$5,-1); }
| DEFINE_KEY TOKEN_KEY STRING '(' INTEGER ')' ENDIAN_KEY '=' BIG_KEY { $$ = slgh->defineToken($3,$5,1); }
| tokenprop fielddef { $$ = $1; slgh->addTokenField($1,$2); }
| DEFINE_KEY TOKEN_KEY anysymbol { string errmsg=$3->getName()+": redefined as a token"; yyerror(errmsg.c_str()); YYERROR; }
;

View File

@ -494,7 +494,7 @@ int4 scan_number(char *numtext,YYSTYPE *lval,bool signednum)
[(),\-] { yylval.ch = yytext[0]; return yytext[0]; }
\: { BEGIN(print); slgh->calcContextLayout(); yylval.ch = yytext[0]; return yytext[0]; }
\{ { BEGIN(sem); yylval.ch = yytext[0]; return yytext[0]; }
#.*$
#.*
[\r\ \t\v]+
\n { slgh->nextLine(); }
macro { BEGIN(macroblock); return MACRO_KEY; }
@ -540,7 +540,7 @@ with { BEGIN(pattern); withsection = 1; slgh->calcContextLayout(); return WITH
<defblock>values { return VALUES_KEY; }
<defblock>variables { return VARIABLES_KEY; }
<defblock>pcodeop { return PCODEOP_KEY; }
<defblock>#.*$
<defblock>#.*
<defblock>[a-zA-Z_.][a-zA-Z0-9_.]* { return find_symbol(); }
<defblock>[0-9]|[1-9][0-9]+ { return scan_number(yytext,&yylval,false); }
<defblock>0x[0-9a-fA-F]+ { return scan_number(yytext,&yylval,false); }
@ -582,7 +582,7 @@ with { BEGIN(pattern); withsection = 1; slgh->calcContextLayout(); return WITH
<pattern>\| { yylval.ch = yytext[0]; return (actionon==0) ? yytext[0] : OP_OR; }
<pattern>\^ { return OP_XOR; }
<pattern>[=(),:;+\-*/~<>] { yylval.ch = yytext[0]; return yytext[0]; }
<pattern>#.*$
<pattern>#.*
<pattern>[a-zA-Z_.][a-zA-Z0-9_.]* { return find_symbol(); }
<pattern>[0-9]|[1-9][0-9]+ { return scan_number(yytext,&yylval,true); }
<pattern>0x[0-9a-fA-F]+ { return scan_number(yytext,&yylval,true); }
@ -648,7 +648,7 @@ with { BEGIN(pattern); withsection = 1; slgh->calcContextLayout(); return WITH
<sem>build { return BUILD_KEY; }
<sem>local { return LOCAL_KEY; }
<sem>[=(),:\[\];!&|^+\-*/%~<>] { yylval.ch = yytext[0]; return yytext[0]; }
<sem>#.*$
<sem>#.*
<sem>[a-zA-Z_.][a-zA-Z0-9_.]* { return find_symbol(); }
<sem>[0-9]|[1-9][0-9]+ { return scan_number(yytext,&yylval,false); }
<sem>0x[0-9a-fA-F]+ { return scan_number(yytext,&yylval,false); }

View File

@ -4,7 +4,7 @@
<title>SLEIGH</title>
<subtitle>A Language for Rapid Processor Specification</subtitle>
<pubdate>Originally published December 16, 2005</pubdate>
<releaseinfo>Last updated September 5, 2019</releaseinfo>
<releaseinfo>Last updated October 28, 2020</releaseinfo>
</info>
<simplesect>
<info>
@ -573,13 +573,14 @@ define endian=little;
</programlisting>
</informalexample>
This defines how the processor interprets contiguous sequences of
bytes as integers. It effects how integer fields within an instruction
are interpreted (see <xref linkend="sleigh_defining_tokens"/>), and
it also effects the details of how the processor is supposed to
implement atomic operations like integer addition and integer
compare. The specification designer should only need to worry about
these details when labeling instruction fields, otherwise the
specification language will hide endianess issues.
bytes as integers or other values and globally affects values across
all address spaces. It also affects how integer fields
within an instruction are interpreted, (see <xref linkend="sleigh_defining_tokens"/>),
although it is possible to override this setting in the rare case that endianess is
different for data versus instruction encoding.
The specification designer generally only needs to worry about
endianess when labeling instruction fields and when defining overlapping registers,
otherwise the specification language hides endianess issues.
</para>
</sect2>
<sect2>
@ -966,7 +967,7 @@ individual <emphasis>constructor</emphasis> (defined in <xref linkend="sleigh_co
defines a local scope for operand names. As with most languages, a
local symbol with the same name as a global
symbol <emphasis>hides</emphasis> the global symbol while that scope
is in affect.
is in effect.
</para>
</sect2>
<sect2 id="sleigh_predefined_symbols">
@ -1057,8 +1058,22 @@ there are one or more field declarations specifying the name of the
field and the range of bits within the token making up the field. The
size of a field does <emphasis>not</emphasis> need to be a multiple of
8. The range is inclusive where the least significant bit in the token
is labeled 0. The endianess of the processor will effect this labeling
when defining tokens that are bigger than 1 byte. After each field
is labeled 0. When defining tokens that are bigger than 1 byte, the
global endianess setting (See <xref linkend="sleigh_endianess_definition"/>)
will affect this labeling. Although it is rarely required, it is possible to override
the global endianess setting for a specific token by appending either the qualifier
<emphasis role="bold">endian=little</emphasis> or <emphasis role="bold">endian=big</emphasis>
immediately after the token name and size. For instance:
<informalexample>
<programlisting>
define token instr ( 32 ) endian=little op0=(0,15) <emphasis role="weak">...</emphasis>
</programlisting>
</informalexample>
The token <emphasis>instr</emphasis> is overridden to be little endian.
This override applies to all fields defined for the token but affects no other tokens.
</para>
<para>
After each field
declaration, there can be zero or more of the following attribute
keywords:
<informalexample>
@ -2023,7 +2038,7 @@ assignment to such a variable changes the context in which the current
instruction is being disassembled and can potentially have a drastic
effect on how the rest of the instruction is disassembled. An
assignment of this form is considered local to the instruction and
will not effect how other instructions are parsed. The context
will not affect how other instructions are parsed. The context
variable is reset to its original value before parsing other
instructions. The disassembly action may also contain one or
more <emphasis role="bold">globalset</emphasis> directives, which
@ -2547,7 +2562,7 @@ the table symbol <emphasis>mode</emphasis>. When this constructor is
matched, as part of a more complicated instruction, the
symbol <emphasis>mode</emphasis> will represent the original semantic
value of <emphasis>reg</emphasis> but with the standard post-increment
side effect.
side-effect.
</para>
<para>
The table symbol associated with the constructor becomes
@ -3724,7 +3739,7 @@ blr is opcode=35 &amp; reg=15 &amp; LRset=1 { return [lr]; }
An alternative to the <emphasis role="bold">noflow</emphasis> attribute is to simply issue
multiple directives within a single constructor, so an explicit end to a context change
can be given. The value of the variable exported to the global state
is the one in affect at the point where the directive is issued. Thus,
is the one in effect at the point where the directive is issued. Thus,
after one <emphasis role="bold">globalset</emphasis>, the same context
variable can be assigned a different value, followed by
another <emphasis role="bold">globalset</emphasis> for a different
@ -3735,7 +3750,7 @@ Because context in SLEIGH is controlled by a disassembly process,
there are some basic caveats to the use of
the <emphasis role="bold">globalset</emphasis> directive. With
<emphasis>flowing</emphasis> context changes,
there is no guarantee of what global state will be in affect at a
there is no guarantee of what global state will be in effect at a
particular address. During disassembly, at any given
point, the process may not have uncovered all the relevant directives,
and the known directives may not necessarily be consistent. In

View File

@ -119,6 +119,7 @@ tokens {
OP_SUBTABLE;
OP_TABLE;
OP_TOKEN;
OP_TOKEN_ENDIAN;
OP_TRUNCATION_SIZE;
OP_TYPE;
OP_UNIMPL;

View File

@ -183,10 +183,20 @@ tokendef
if (sym != null) {
redefinedError(sym, n, "token");
} else {
$tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(), $i.value.intValue());
$tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(), $i.value.intValue(), 0);
}
}
} fielddefs)
| ^(OP_TOKEN_ENDIAN n=specific_identifier["token definition"] i=integer s=endian {
if (n != null) {
SleighSymbol sym = sc.findSymbol($n.value.getText());
if (sym != null) {
redefinedError(sym, n, "token");
} else {
$tokendef::tokenSymbol = sc.defineToken(find(n), $n.value.getText(), $i.value.intValue(), $s.value ==0 ? -1 : 1);
}
}
} fielddefs)
;
fielddefs

View File

@ -60,6 +60,7 @@ aligndef
tokendef
: ^(OP_TOKEN n=identifier i=integer { out("define token " + $n.value + "(" + $i.value + ")"); } fielddefs)
| ^(OP_TOKEN_ENDIAN n=identifier i=integer s=endian { out("define token endian" + $n.value + "(" + $i.value + ")"); } fielddefs)
;
fielddefs

View File

@ -74,6 +74,7 @@ aligndef
tokendef
: lc=KEY_DEFINE KEY_TOKEN identifier LPAREN integer rp=RPAREN fielddefs[$rp] -> ^(OP_TOKEN[$lc, "define token"] identifier integer fielddefs)
| lc=KEY_DEFINE KEY_TOKEN identifier LPAREN integer RPAREN rp=KEY_ENDIAN ASSIGN endian fielddefs[$rp] -> ^(OP_TOKEN_ENDIAN[$lc, "define token"] identifier integer endian fielddefs)
;
fielddefs[Token lc]

View File

@ -888,11 +888,13 @@ public class SleighLanguage implements Language {
throw new SleighException(".sla file for " + getLanguageID() + " has the wrong format");
}
boolean isBigEndian = SpecXmlUtils.decodeBoolean(el.getAttribute("bigendian"));
// check the instruction endianess, not the program data endianess
if (isBigEndian ^ description.getInstructionEndian().isBigEndian()) {
throw new SleighException(
".ldefs says " + getLanguageID() + " is " + description.getInstructionEndian() +
" but .sla says " + el.getAttribute("bigendian"));
if (isBigEndian ^ description.getEndian().isBigEndian()) {
if (description.getInstructionEndian().isBigEndian() == description.getEndian()
.isBigEndian()) {
throw new SleighException(
".ldefs says " + getLanguageID() + " is " + description.getEndian() +
" but .sla says " + el.getAttribute("bigendian"));
}
}
uniqueBase = SpecXmlUtils.decodeLong(el.getAttribute("uniqbase"));
alignment = SpecXmlUtils.decodeInt(el.getAttribute("align"));

View File

@ -529,8 +529,8 @@ public class SleighCompile extends SleighBase {
static int findCollision(Map<Long, Integer> local2Operand, ArrayList<Long> locals,
int operand) {
Integer boxOperand = Integer.valueOf(operand);
for (int i = 0; i < locals.size(); ++i) {
Integer previous = local2Operand.putIfAbsent(locals.get(i), boxOperand);
for (Long local : locals) {
Integer previous = local2Operand.putIfAbsent(local, boxOperand);
if (previous != null) {
if (previous.intValue() != operand) {
return previous.intValue();
@ -842,7 +842,7 @@ public class SleighCompile extends SleighBase {
}
// Parser functions
public TokenSymbol defineToken(Location location, String name, long sz) {
public TokenSymbol defineToken(Location location, String name, long sz, int endian) {
entry("defineToken", location, name, sz);
int size = (int) sz;
if ((size & 7) != 0) {
@ -853,8 +853,15 @@ public class SleighCompile extends SleighBase {
else {
size = size / 8;
}
boolean isBig;
if (endian == 0) {
isBig = isBigEndian();
}
else {
isBig = (endian > 0);
}
ghidra.pcodeCPort.context.Token newtoken =
new ghidra.pcodeCPort.context.Token(name, size, isBigEndian(), tokentable.size());
new ghidra.pcodeCPort.context.Token(name, size, isBig, tokentable.size());
tokentable.push_back(newtoken);
TokenSymbol res = new TokenSymbol(location, newtoken);
addSymbol(res);

View File

@ -32,7 +32,11 @@
# and the destination is not the upper half of the register (ie, bit 30 q=0)
# then the unused remaining upper bits must be set to 0.
@if DATA_ENDIAN == "little"
define endian=little;
@else
define endian=big;
@endif
define alignment=4;
# Unlike the above, these are preprocessor macros. Use them with e.g. $(TAG_GRANULE) in SLEIGH statements.
@ -1008,7 +1012,7 @@ define context contextreg
ShowMemTag = (24,24) noflow
;
define token instrAARCH64 (32)
define token instrAARCH64 (32) endian = little
Rm = (16,20)
Rn = (5,9)
@ -2644,27 +2648,86 @@ vIndexHLM: val is b_2223=0 & b_2121 & b_1111 & b_2020 [ val = b_1111 << 2 | b_21
vIndexHL: val is b_2223=0b01 & b_21 & b_11 [ val = b_11 << 1 | b_21; ] { export *[const]:8 val; }
vIndexHL: b_11 is b_2223=0b10 & b_11 { export *[const]:8 b_11; }
Re_VPR128.B.vIndex: Re_VPR128.B^"["^vIndex^"]" is Re_VPR128.B & vIndex { }
Re_VPR128.S.vIndex: Re_VPR128.S^"["^vIndex^"]" is Re_VPR128.S & vIndex { }
Re_VPR128.D.vIndex: Re_VPR128.D^"["^vIndex^"]" is Re_VPR128.D & vIndex { }
@if DATA_ENDIAN == "little"
Re_VPR128.B.sel: Re_VPR128, val is Re_VPR128 & b_2222=0 & b_2121 & b_1111 [ val = 0x5000 + 32*Re_VPR128 + b_1111 * 2 + b_2121; ] { export *[register]:1 val; }
Re_VPR128.B.sel: Re_VPR128, val is Re_VPR128 & b_2222=1 & b_2121=0 & b_1111 [ val = 0x5000 + 32*Re_VPR128 + b_1111; ] { export *[register]:1 val; }
Re_VPR128.S.sel: Re_VPR128, val is Re_VPR128 & b_2222=0 & b_2121 & b_1111 [ val = 0x5000 + 32*Re_VPR128 + (b_1111 * 2 + b_2121) * 4; ] { export *[register]:4 val; }
Re_VPR128.S.sel: Re_VPR128, val is Re_VPR128 & b_2222=1 & b_2121=0 & b_1111 [ val = 0x5000 + 32*Re_VPR128 + b_1111 * 4; ] { export *[register]:4 val; }
Re_VPR128.D.sel: Re_VPR128, val is Re_VPR128 & b_2222=0 & b_2121 & b_1111 [ val = 0x5000 + 32*Re_VPR128 + (b_1111 * 2 + b_2121) * 8; ] { export *[register]:8 val; }
Re_VPR128.D.sel: Re_VPR128, val is Re_VPR128 & b_2222=1 & b_2121=0 & b_1111 [ val = 0x5000 + 32*Re_VPR128 + b_1111 * 8; ] { export *[register]:8 val; }
@else
Re_VPR128.B.sel: Re_VPR128, val is Re_VPR128 & b_2222=0 & b_2121 & b_1111 [ val = 0x501f + 32*Re_VPR128 - b_1111 * 2 - b_2121; ] { export *[register]:1 val; }
Re_VPR128.B.sel: Re_VPR128, val is Re_VPR128 & b_2222=1 & b_2121=0 & b_1111 [ val = 0x501f + 32*Re_VPR128 - b_1111; ] { export *[register]:1 val; }
Re_VPR128.S.sel: Re_VPR128, val is Re_VPR128 & b_2222=0 & b_2121 & b_1111 [ val = 0x501c + 32*Re_VPR128 - (b_1111 * 2 + b_2121) * 4; ] { export *[register]:4 val; }
Re_VPR128.S.sel: Re_VPR128, val is Re_VPR128 & b_2222=1 & b_2121=0 & b_1111 [ val = 0x501c + 32*Re_VPR128 - b_1111 * 4; ] { export *[register]:4 val; }
Re_VPR128.D.sel: Re_VPR128, val is Re_VPR128 & b_2222=0 & b_2121 & b_1111 [ val = 0x5018 + 32*Re_VPR128 - (b_1111 * 2 + b_2121) * 8; ] { export *[register]:8 val; }
Re_VPR128.D.sel: Re_VPR128, val is Re_VPR128 & b_2222=1 & b_2121=0 & b_1111 [ val = 0x5018 + 32*Re_VPR128 - b_1111 * 8; ] { export *[register]:8 val; }
@endif
Rd_VPR128.B.imm_neon_uimm4: Rd_VPR128.B^"["^imm_neon_uimm4^"]" is Rd_VPR128.B & imm_neon_uimm4 { export Rd_VPR128.B; }
Rd_VPR128.H.imm_neon_uimm3: Rd_VPR128.H^"["^imm_neon_uimm3^"]" is Rd_VPR128.H & imm_neon_uimm3 { export Rd_VPR128.H; }
Rd_VPR128.S.imm_neon_uimm2: Rd_VPR128.S^"["^imm_neon_uimm2^"]" is Rd_VPR128.S & imm_neon_uimm2 { export Rd_VPR128.S; }
Rd_VPR128.D.imm_neon_uimm1: Rd_VPR128.D^"["^imm_neon_uimm1^"]" is Rd_VPR128.D & imm_neon_uimm1 { export Rd_VPR128.D; }
Re_VPR128.B.vIndex: Re_VPR128.B^"["^vIndex^"]" is Re_VPR128.B & vIndex & Re_VPR128.B.sel { export Re_VPR128.B.sel; }
Re_VPR128.S.vIndex: Re_VPR128.S^"["^vIndex^"]" is Re_VPR128.S & vIndex & Re_VPR128.S.sel { export Re_VPR128.S.sel; }
Re_VPR128.D.vIndex: Re_VPR128.D^"["^vIndex^"]" is Re_VPR128.D & vIndex & Re_VPR128.D.sel { export Re_VPR128.D.sel; }
Rn_VPR128.B.immN_neon_uimm4: Rn_VPR128.B^"["^immN_neon_uimm4^"]" is Rn_VPR128.B & immN_neon_uimm4 { export Rn_VPR128.B; }
Rn_VPR128.H.immN_neon_uimm3: Rn_VPR128.H^"["^immN_neon_uimm3^"]" is Rn_VPR128.H & immN_neon_uimm3 { export Rn_VPR128.H; }
Rn_VPR128.S.immN_neon_uimm2: Rn_VPR128.S^"["^immN_neon_uimm2^"]" is Rn_VPR128.S & immN_neon_uimm2 { export Rn_VPR128.S; }
Rn_VPR128.D.immN_neon_uimm1: Rn_VPR128.D^"["^immN_neon_uimm1^"]" is Rn_VPR128.D & immN_neon_uimm1 { export Rn_VPR128.D; }
@if DATA_ENDIAN == "little"
Rd_VPR128.B.sel: Rd_VPR128, val is Rd_VPR128 & imm_neon_uimm4 [ val = 0x5000 + 32*Rd_VPR128 + imm_neon_uimm4; ] { export *[register]:1 val; }
Rd_VPR128.H.sel: Rd_VPR128, val is Rd_VPR128 & imm_neon_uimm3 [ val = 0x5000 + 32*Rd_VPR128 + 2*imm_neon_uimm3; ] { export *[register]:2 val; }
Rd_VPR128.S.sel: Rd_VPR128, val is Rd_VPR128 & imm_neon_uimm2 [ val = 0x5000 + 32*Rd_VPR128 + 4*imm_neon_uimm2; ] { export *[register]:4 val; }
Rd_VPR128.D.sel: Rd_VPR128, val is Rd_VPR128 & imm_neon_uimm1 [ val = 0x5000 + 32*Rd_VPR128 + 8*imm_neon_uimm1; ] { export *[register]:8 val; }
@else
Rd_VPR128.B.sel: Rd_VPR128, val is Rd_VPR128 & imm_neon_uimm4 [ val = 0x501f + 32*Rd_VPR128 - imm_neon_uimm4; ] { export *[register]:1 val; }
Rd_VPR128.H.sel: Rd_VPR128, val is Rd_VPR128 & imm_neon_uimm3 [ val = 0x501e + 32*Rd_VPR128 - 2*imm_neon_uimm3; ] { export *[register]:2 val; }
Rd_VPR128.S.sel: Rd_VPR128, val is Rd_VPR128 & imm_neon_uimm2 [ val = 0x501c + 32*Rd_VPR128 - 4*imm_neon_uimm2; ] { export *[register]:4 val; }
Rd_VPR128.D.sel: Rd_VPR128, val is Rd_VPR128 & imm_neon_uimm1 [ val = 0x5018 + 32*Rd_VPR128 - 8*imm_neon_uimm1; ] { export *[register]:8 val; }
@endif
Rd_VPR128.B.imm_neon_uimm4: Rd_VPR128.B^"["^imm_neon_uimm4^"]" is Rd_VPR128.B & imm_neon_uimm4 & Rd_VPR128.B.sel { export Rd_VPR128.B.sel; }
Rd_VPR128.H.imm_neon_uimm3: Rd_VPR128.H^"["^imm_neon_uimm3^"]" is Rd_VPR128.H & imm_neon_uimm3 & Rd_VPR128.H.sel { export Rd_VPR128.H.sel; }
Rd_VPR128.S.imm_neon_uimm2: Rd_VPR128.S^"["^imm_neon_uimm2^"]" is Rd_VPR128.S & imm_neon_uimm2 & Rd_VPR128.S.sel { export Rd_VPR128.S.sel; }
Rd_VPR128.D.imm_neon_uimm1: Rd_VPR128.D^"["^imm_neon_uimm1^"]" is Rd_VPR128.D & imm_neon_uimm1 & Rd_VPR128.D.sel { export Rd_VPR128.D.sel; }
Rn_VPR128.B.imm_neon_uimm4: Rn_VPR128.B^"["^imm_neon_uimm4^"]" is Rn_VPR128.B & imm_neon_uimm4 { export Rn_VPR128.B; }
Rn_VPR128.H.imm_neon_uimm3: Rn_VPR128.H^"["^imm_neon_uimm3^"]" is Rn_VPR128.H & imm_neon_uimm3 { export Rn_VPR128.H; }
Rn_VPR128.S.imm_neon_uimm2: Rn_VPR128.S^"["^imm_neon_uimm2^"]" is Rn_VPR128.S & imm_neon_uimm2 { export Rn_VPR128.S; }
Rn_VPR128.D.imm_neon_uimm1: Rn_VPR128.D^"["^imm_neon_uimm1^"]" is Rn_VPR128.D & imm_neon_uimm1 { export Rn_VPR128.D; }
@if DATA_ENDIAN == "little"
Rn_VPR128.B.selN: Rn_VPR128, val is Rn_VPR128 & immN_neon_uimm4 [ val = 0x5000 + 32*Rn_VPR128 + immN_neon_uimm4; ] { export *[register]:1 val; }
Rn_VPR128.H.selN: Rn_VPR128, val is Rn_VPR128 & immN_neon_uimm3 [ val = 0x5000 + 32*Rn_VPR128 + 2*immN_neon_uimm3; ] { export *[register]:2 val; }
Rn_VPR128.S.selN: Rn_VPR128, val is Rn_VPR128 & immN_neon_uimm2 [ val = 0x5000 + 32*Rn_VPR128 + 4*immN_neon_uimm2; ] { export *[register]:4 val; }
Rn_VPR128.D.selN: Rn_VPR128, val is Rn_VPR128 & immN_neon_uimm1 [ val = 0x5000 + 32*Rn_VPR128 + 8*immN_neon_uimm1; ] { export *[register]:8 val; }
@else
Rn_VPR128.B.selN: Rn_VPR128, val is Rn_VPR128 & immN_neon_uimm4 [ val = 0x501f + 32*Rn_VPR128 - immN_neon_uimm4; ] { export *[register]:1 val; }
Rn_VPR128.H.selN: Rn_VPR128, val is Rn_VPR128 & immN_neon_uimm3 [ val = 0x501e + 32*Rn_VPR128 - 2*immN_neon_uimm3; ] { export *[register]:2 val; }
Rn_VPR128.S.selN: Rn_VPR128, val is Rn_VPR128 & immN_neon_uimm2 [ val = 0x501c + 32*Rn_VPR128 - 4*immN_neon_uimm2; ] { export *[register]:4 val; }
Rn_VPR128.D.selN: Rn_VPR128, val is Rn_VPR128 & immN_neon_uimm1 [ val = 0x5018 + 32*Rn_VPR128 - 8*immN_neon_uimm1; ] { export *[register]:8 val; }
@endif
Rn_VPR128.B.immN_neon_uimm4: Rn_VPR128.B^"["^immN_neon_uimm4^"]" is Rn_VPR128.B & immN_neon_uimm4 & Rn_VPR128.B.selN { export Rn_VPR128.B.selN; }
Rn_VPR128.H.immN_neon_uimm3: Rn_VPR128.H^"["^immN_neon_uimm3^"]" is Rn_VPR128.H & immN_neon_uimm3 & Rn_VPR128.H.selN { export Rn_VPR128.H.selN; }
Rn_VPR128.S.immN_neon_uimm2: Rn_VPR128.S^"["^immN_neon_uimm2^"]" is Rn_VPR128.S & immN_neon_uimm2 & Rn_VPR128.S.selN { export Rn_VPR128.S.selN; }
Rn_VPR128.D.immN_neon_uimm1: Rn_VPR128.D^"["^immN_neon_uimm1^"]" is Rn_VPR128.D & immN_neon_uimm1 & Rn_VPR128.D.selN { export Rn_VPR128.D.selN; }
@if DATA_ENDIAN == "little"
Rn_VPR128.B.sel: Rn_VPR128, val is Rn_VPR128 & imm_neon_uimm4 [ val = 0x5000 + 32*Rn_VPR128 + imm_neon_uimm4; ] { export *[register]:1 val; }
Rn_VPR128.H.sel: Rn_VPR128, val is Rn_VPR128 & imm_neon_uimm3 [ val = 0x5000 + 32*Rn_VPR128 + 2*imm_neon_uimm3; ] { export *[register]:2 val; }
Rn_VPR128.S.sel: Rn_VPR128, val is Rn_VPR128 & imm_neon_uimm2 [ val = 0x5000 + 32*Rn_VPR128 + 4*imm_neon_uimm2; ] { export *[register]:4 val; }
Rn_VPR128.D.sel: Rn_VPR128, val is Rn_VPR128 & imm_neon_uimm1 [ val = 0x5000 + 32*Rn_VPR128 + 8*imm_neon_uimm1; ] { export *[register]:8 val; }
@else
Rn_VPR128.B.sel: Rn_VPR128, val is Rn_VPR128 & imm_neon_uimm4 [ val = 0x501f + 32*Rn_VPR128 - imm_neon_uimm4; ] { export *[register]:1 val; }
Rn_VPR128.H.sel: Rn_VPR128, val is Rn_VPR128 & imm_neon_uimm3 [ val = 0x501e + 32*Rn_VPR128 - 2*imm_neon_uimm3; ] { export *[register]:2 val; }
Rn_VPR128.S.sel: Rn_VPR128, val is Rn_VPR128 & imm_neon_uimm2 [ val = 0x501c + 32*Rn_VPR128 - 4*imm_neon_uimm2; ] { export *[register]:4 val; }
Rn_VPR128.D.sel: Rn_VPR128, val is Rn_VPR128 & imm_neon_uimm1 [ val = 0x5018 + 32*Rn_VPR128 - 8*imm_neon_uimm1; ] { export *[register]:8 val; }
@endif
Rn_VPR128.B.imm_neon_uimm4: Rn_VPR128.B^"["^imm_neon_uimm4^"]" is Rn_VPR128.B & imm_neon_uimm4 & Rn_VPR128.B.sel { export Rn_VPR128.B.sel; }
Rn_VPR128.H.imm_neon_uimm3: Rn_VPR128.H^"["^imm_neon_uimm3^"]" is Rn_VPR128.H & imm_neon_uimm3 & Rn_VPR128.H.sel { export Rn_VPR128.H.sel; }
Rn_VPR128.S.imm_neon_uimm2: Rn_VPR128.S^"["^imm_neon_uimm2^"]" is Rn_VPR128.S & imm_neon_uimm2 & Rn_VPR128.S.sel { export Rn_VPR128.S.sel; }
Rn_VPR128.D.imm_neon_uimm1: Rn_VPR128.D^"["^imm_neon_uimm1^"]" is Rn_VPR128.D & imm_neon_uimm1 & Rn_VPR128.D.sel { export Rn_VPR128.D.sel; }
Re_VPR128.H.vIndexHL: Re_VPR128.H^"["^vIndexHL^"]" is Re_VPR128.H & vIndexHL { }
Re_VPR128Lo.H.vIndexHLM: Re_VPR128Lo.H^"["^vIndexHLM^"]" is Re_VPR128Lo.H & vIndexHLM { }
@if DATA_ENDIAN == "little"
Re_VPR128Lo.H.sel: Re_VPR128, val is Re_VPR128 & b_2223=2 & b_2121 & b_1111 [ val = 0x5000 + 32*Re_VPR128 + (b_1111 * 2 + b_2121)*2; ] { export *[register]:2 val; }
Re_VPR128Lo.H.sel: Re_VPR128, val is Re_VPR128 & b_2223=1 & b_2121 & b_1111 & b_2020 [ val = 0x5000 + 32*Re_VPR128 + (b_1111*4 + b_2121*2 + b_2020)*2; ] { export *[register]:2 val; }
Re_VPR128Lo.H.sel: Re_VPR128, val is Re_VPR128 & b_2223=0 & b_2121 & b_1111 & b_2020 [ val = 0x5000 + 32*Re_VPR128 + (b_1111*4 + b_2121*2 + b_2020)*2; ] { export *[register]:2 val; }
@else
Re_VPR128Lo.H.sel: Re_VPR128, val is Re_VPR128 & b_2223=2 & b_2121 & b_1111 [ val = 0x501e + 32*Re_VPR128 - (b_1111 * 2 + b_2121)*2; ] { export *[register]:2 val; }
Re_VPR128Lo.H.sel: Re_VPR128, val is Re_VPR128 & b_2223=1 & b_2121 & b_1111 & b_2020 [ val = 0x501e + 32*Re_VPR128 - (b_1111*4 + b_2121*2 + b_2020)*2; ] { export *[register]:2 val; }
Re_VPR128Lo.H.sel: Re_VPR128, val is Re_VPR128 & b_2223=0 & b_2121 & b_1111 & b_2020 [ val = 0x501e + 32*Re_VPR128 - (b_1111*4 + b_2121*2 + b_2020)*2; ] { export *[register]:2 val; }
@endif
Re_VPR128Lo.H.vIndexHLM: Re_VPR128Lo.H^"["^vIndexHLM^"]" is Re_VPR128Lo.H & vIndexHLM & Re_VPR128Lo.H.sel { export Re_VPR128Lo.H.sel; }
FBitsOp: "#"^fbits is Scale [ fbits = 64 - Scale; ] { export *[const]:2 fbits; }
@ -3193,55 +3256,17 @@ PACIXSP_BTITARGETS: is ShowBTI=0 { }
# These pseudo ops are used in neon
define pcodeop SIMD_COPY;
define pcodeop SIMD_FLOAT;
define pcodeop SIMD_FLOAT2FLOAT;
define pcodeop SIMD_FLOAT_ABS;
define pcodeop SIMD_FLOAT_ADD;
define pcodeop SIMD_FLOAT_DIV;
define pcodeop SIMD_FLOAT_MULT;
define pcodeop SIMD_FLOAT_NEG;
define pcodeop SIMD_FLOAT_SUB;
define pcodeop SIMD_INT;
define pcodeop SIMD_INT_2COMP;
define pcodeop SIMD_INT_ABS;
define pcodeop SIMD_INT_ADD;
define pcodeop SIMD_INT_AND;
define pcodeop SIMD_INT_LEFT;
define pcodeop SIMD_INT_LESS;
define pcodeop SIMD_INT_MULT;
define pcodeop SIMD_INT_NEGATE;
define pcodeop SIMD_INT_OR;
define pcodeop SIMD_INT_RIGHT;
define pcodeop SIMD_INT_SEXT;
define pcodeop SIMD_INT_SLESS;
define pcodeop SIMD_INT_SRIGHT;
define pcodeop SIMD_INT_SUB;
define pcodeop SIMD_INT_XOR;
define pcodeop SIMD_INT_ZEXT;
define pcodeop SIMD_PIECE;
define pcodeop SIMD_TRUNC;
define pcodeop NEON_abs;
define pcodeop NEON_add;
define pcodeop NEON_addhn;
define pcodeop NEON_addhn2;
define pcodeop NEON_addp;
define pcodeop NEON_addv;
define pcodeop NEON_aesd;
define pcodeop NEON_aese;
define pcodeop NEON_aesimc;
define pcodeop NEON_aesmc;
define pcodeop NEON_and;
define pcodeop NEON_bcax;
define pcodeop NEON_bfcvt;
define pcodeop NEON_bfcvtn;
define pcodeop NEON_bfcvtn2;
define pcodeop NEON_bfdot;
define pcodeop NEON_bfmlalb;
define pcodeop NEON_bfmlalt;
define pcodeop NEON_bfmmla;
define pcodeop NEON_bic;
define pcodeop NEON_bif;
define pcodeop NEON_bit;
define pcodeop NEON_bsl;
@ -3256,40 +3281,18 @@ define pcodeop NEON_cmle;
define pcodeop NEON_cmlt;
define pcodeop NEON_cmtst;
define pcodeop NEON_cnt;
define pcodeop NEON_dup;
define pcodeop NEON_eor;
define pcodeop NEON_eor3;
define pcodeop NEON_ext;
define pcodeop NEON_fabd;
define pcodeop NEON_fabs;
define pcodeop NEON_facge;
define pcodeop NEON_facgt;
define pcodeop NEON_fadd;
define pcodeop NEON_faddp;
define pcodeop NEON_fcadd;
define pcodeop NEON_fccmp;
define pcodeop NEON_fccmpe;
define pcodeop NEON_fcmeq;
define pcodeop NEON_fcmge;
define pcodeop NEON_fcmgt;
define pcodeop NEON_fcmla;
define pcodeop NEON_fcmle;
define pcodeop NEON_fcmlt;
define pcodeop NEON_fcmp;
define pcodeop NEON_fcmpe;
define pcodeop NEON_fcsel;
define pcodeop NEON_fcvt;
define pcodeop NEON_fcvt_amnpz_su;
define pcodeop NEON_fcvtl;
define pcodeop NEON_fcvtl2;
define pcodeop NEON_fcvtn;
define pcodeop NEON_fcvtn2;
define pcodeop NEON_fcvtxn;
define pcodeop NEON_fcvtxn2;
define pcodeop NEON_fcvtzs;
define pcodeop NEON_fcvtzu;
define pcodeop NEON_fdiv;
define pcodeop NEON_fjcvtzs;
define pcodeop NEON_fmadd;
define pcodeop NEON_fmax;
define pcodeop NEON_fmaxnm;
@ -3303,50 +3306,22 @@ define pcodeop NEON_fminnmp;
define pcodeop NEON_fminnmv;
define pcodeop NEON_fminp;
define pcodeop NEON_fminv;
define pcodeop NEON_fmla;
define pcodeop NEON_fmlal;
define pcodeop NEON_fmlal2;
define pcodeop NEON_fmls;
define pcodeop NEON_fmlsl;
define pcodeop NEON_fmlsl2;
define pcodeop NEON_fmov;
define pcodeop NEON_fmsub;
define pcodeop NEON_fmul;
define pcodeop NEON_fmulx;
define pcodeop NEON_fneg;
define pcodeop NEON_fnmadd;
define pcodeop NEON_fnmsub;
define pcodeop NEON_fnmul;
define pcodeop NEON_frecpe;
define pcodeop NEON_frecps;
define pcodeop NEON_frecpx;
define pcodeop NEON_frint_aimnpxz;
define pcodeop NEON_frsqrte;
define pcodeop NEON_frsqrts;
define pcodeop NEON_fsqrt;
define pcodeop NEON_fsub;
define pcodeop NEON_ldnp1;
define pcodeop NEON_ldnp2;
define pcodeop NEON_ldp1;
define pcodeop NEON_ldp2;
define pcodeop NEON_ldr;
define pcodeop NEON_ldur;
define pcodeop NEON_mla;
define pcodeop NEON_mls;
define pcodeop NEON_mov;
define pcodeop NEON_movi;
define pcodeop NEON_mul;
define pcodeop NEON_mvn;
define pcodeop NEON_mvni;
define pcodeop NEON_neg;
define pcodeop NEON_orn;
define pcodeop NEON_orr;
define pcodeop NEON_pmul;
define pcodeop NEON_pmull;
define pcodeop NEON_pmull2;
define pcodeop NEON_raddhn;
define pcodeop NEON_raddhn2;
define pcodeop NEON_rax1;
define pcodeop NEON_rbit;
define pcodeop NEON_rev16;
define pcodeop NEON_rev32;
@ -3356,22 +3331,11 @@ define pcodeop NEON_rshrn2;
define pcodeop NEON_rsubhn;
define pcodeop NEON_rsubhn2;
define pcodeop NEON_saba;
define pcodeop NEON_sabal;
define pcodeop NEON_sabal2;
define pcodeop NEON_sabd;
define pcodeop NEON_sabdl;
define pcodeop NEON_sabdl2;
define pcodeop NEON_sadalp;
define pcodeop NEON_saddl;
define pcodeop NEON_saddl2;
define pcodeop NEON_saddlp;
define pcodeop NEON_saddlv;
define pcodeop NEON_saddw;
define pcodeop NEON_saddw2;
define pcodeop NEON_scvtf;
define pcodeop NEON_sdot;
define pcodeop NEON_sha1c;
define pcodeop NEON_sha1h;
define pcodeop NEON_sha1m;
define pcodeop NEON_sha1p;
define pcodeop NEON_sha1su0;
@ -3386,10 +3350,6 @@ define pcodeop NEON_sha512su0;
define pcodeop NEON_sha512su1;
define pcodeop NEON_shadd;
define pcodeop NEON_shl;
define pcodeop NEON_shll;
define pcodeop NEON_shll2;
define pcodeop NEON_shrn;
define pcodeop NEON_shrn2;
define pcodeop NEON_shsub;
define pcodeop NEON_sli;
define pcodeop NEON_sm3partw1;
@ -3407,24 +3367,10 @@ define pcodeop NEON_smaxv;
define pcodeop NEON_smin;
define pcodeop NEON_sminp;
define pcodeop NEON_sminv;
define pcodeop NEON_smlal;
define pcodeop NEON_smlal2;
define pcodeop NEON_smlsl;
define pcodeop NEON_smlsl2;
define pcodeop NEON_smov;
define pcodeop NEON_smmla;
define pcodeop NEON_smull;
define pcodeop NEON_smull2;
define pcodeop NEON_sqabs;
define pcodeop NEON_sqadd;
define pcodeop NEON_sqdmlal;
define pcodeop NEON_sqdmlal2;
define pcodeop NEON_sqdmlsl;
define pcodeop NEON_sqdmlsl2;
define pcodeop NEON_sqdmulh;
define pcodeop NEON_sqdmull;
define pcodeop NEON_sqdmull2;
define pcodeop NEON_sqneg;
define pcodeop NEON_sqrdml_as_h;
define pcodeop NEON_sqrdmulh;
define pcodeop NEON_sqrshl;
@ -3447,45 +3393,12 @@ define pcodeop NEON_srhadd;
define pcodeop NEON_sri;
define pcodeop NEON_srshl;
define pcodeop NEON_srshr;
define pcodeop NEON_srsra;
define pcodeop NEON_sshl;
define pcodeop NEON_sshll;
define pcodeop NEON_sshll2;
define pcodeop NEON_sshr;
define pcodeop NEON_ssra;
define pcodeop NEON_ssubl;
define pcodeop NEON_ssubl2;
define pcodeop NEON_ssubw;
define pcodeop NEON_ssubw2;
define pcodeop NEON_stnp1;
define pcodeop NEON_stnp2;
define pcodeop NEON_stp1;
define pcodeop NEON_stp2;
define pcodeop NEON_str;
define pcodeop NEON_stur;
define pcodeop NEON_sub;
define pcodeop NEON_subhn;
define pcodeop NEON_subhn2;
define pcodeop NEON_sudot;
define pcodeop NEON_suqadd;
define pcodeop NEON_sxtl;
define pcodeop NEON_sxtl2;
define pcodeop NEON_tblx;
define pcodeop NEON_trn1;
define pcodeop NEON_trn2;
define pcodeop NEON_uaba;
define pcodeop NEON_uabal;
define pcodeop NEON_uabal2;
define pcodeop NEON_uabd;
define pcodeop NEON_uabdl;
define pcodeop NEON_uabdl2;
define pcodeop NEON_uadalp;
define pcodeop NEON_uaddl;
define pcodeop NEON_uaddl2;
define pcodeop NEON_uaddlp;
define pcodeop NEON_uaddlv;
define pcodeop NEON_uaddw;
define pcodeop NEON_uaddw2;
define pcodeop NEON_ucvtf;
define pcodeop NEON_udot;
define pcodeop NEON_uhadd;
@ -3496,14 +3409,8 @@ define pcodeop NEON_umaxv;
define pcodeop NEON_umin;
define pcodeop NEON_uminp;
define pcodeop NEON_uminv;
define pcodeop NEON_umlal;
define pcodeop NEON_umlal2;
define pcodeop NEON_umlsl;
define pcodeop NEON_umlsl2;
define pcodeop NEON_ummla;
define pcodeop NEON_umov;
define pcodeop NEON_umull;
define pcodeop NEON_umull2;
define pcodeop NEON_uqadd;
define pcodeop NEON_uqrshl;
define pcodeop NEON_uqrshrn;
@ -3519,28 +3426,10 @@ define pcodeop NEON_urhadd;
define pcodeop NEON_urshl;
define pcodeop NEON_urshr;
define pcodeop NEON_ursqrte;
define pcodeop NEON_ursra;
define pcodeop NEON_usdot;
define pcodeop NEON_ushl;
define pcodeop NEON_ushll;
define pcodeop NEON_ushll2;
define pcodeop NEON_ushr;
define pcodeop NEON_usmmla;
define pcodeop NEON_usqadd;
define pcodeop NEON_usra;
define pcodeop NEON_usubl;
define pcodeop NEON_usubl2;
define pcodeop NEON_usubw;
define pcodeop NEON_usubw2;
define pcodeop NEON_uxtl;
define pcodeop NEON_uxtl2;
define pcodeop NEON_uzp1;
define pcodeop NEON_uzp2;
define pcodeop NEON_xar;
define pcodeop NEON_xtn;
define pcodeop NEON_xtn2;
define pcodeop NEON_zip1;
define pcodeop NEON_zip2;
# These pseudo ops are automatically generated
@ -4013,112 +3902,59 @@ macro set_NZCV(value, condMask)
# Macro to access simd lanes
macro simd_address_at(dest, reg, elem, esize, vsize)
{
@if DATA_ENDIAN == "little"
dest = &reg + elem * esize;
@else
dest = &reg + vsize - esize - elem * esize;
@endif
}
# Macros to zero the high bits of the Z or Q registers
# These are friendlier to the decompiler
macro zext_zb(reg)
{
@if DATA_ENDIAN == "little"
reg[8,56] = 0;
reg[64,64] = 0;
reg[128,64] = 0;
reg[192,64] = 0;
@else
reg[192,56] = 0;
reg[128,64] = 0;
reg[64,64] = 0;
reg[0,64] = 0;
@endif
}
macro zext_zh(reg)
{
@if DATA_ENDIAN == "little"
reg[16,48] = 0;
reg[64,64] = 0;
reg[128,64] = 0;
reg[192,64] = 0;
@else
reg[192,48] = 0;
reg[128,64] = 0;
reg[64,64] = 0;
reg[0,64] = 0;
@endif
}
macro zext_zs(reg)
{
@if DATA_ENDIAN == "little"
reg[32,32] = 0;
reg[64,64] = 0;
reg[128,64] = 0;
reg[192,64] = 0;
@else
reg[192,32] = 0;
reg[128,64] = 0;
reg[64,64] = 0;
reg[0,64] = 0;
@endif
}
macro zext_zd(reg)
{
@if DATA_ENDIAN == "little"
reg[64,64] = 0;
reg[128,64] = 0;
reg[192,64] = 0;
@else
reg[0,64] = 0;
reg[64,64] = 0;
reg[128,64] = 0;
@endif
}
macro zext_zq(reg)
{
@if DATA_ENDIAN == "little"
reg[128,64] = 0;
reg[192,64] = 0;
@else
reg[0,64] = 0;
reg[64,64] = 0;
@endif
}
macro zext_rb(reg)
{
@if DATA_ENDIAN == "little"
reg[8,56] = 0;
@else
reg[0,56] = 0;
@endif
}
macro zext_rh(reg)
{
@if DATA_ENDIAN == "little"
reg[16,48] = 0;
@else
reg[0,48] = 0;
@endif
}
macro zext_rs(reg)
{
@if DATA_ENDIAN == "little"
reg[32,32] = 0;
@else
reg[0,32] = 0;
@endif
}
# SECTION instructions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// BLANK:
// COPY:
registerPcodeOpBehavior("SIMD_COPY", new SIMD_COPY());
// registerPcodeOpBehavior("SIMD_COPY", new SIMD_COPY());
// LOAD:
// STORE:
// BRANCH:
@ -53,41 +53,41 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// INT_LESS:
// INT_LESSEQUAL:
// INT_ZEXT:
registerPcodeOpBehavior("SIMD_INT_ZEXT", new SIMD_INT_ZEXT());
// registerPcodeOpBehavior("SIMD_INT_ZEXT", new SIMD_INT_ZEXT());
// INT_SEXT:
registerPcodeOpBehavior("SIMD_INT_SEXT", new SIMD_INT_SEXT());
// registerPcodeOpBehavior("SIMD_INT_SEXT", new SIMD_INT_SEXT());
// INT_ABS (no equivalent SLEIGH primitive):
registerPcodeOpBehavior("MP_INT_ABS", new MP_INT_ABS());
registerPcodeOpBehavior("SIMD_INT_ABS", new SIMD_INT_ABS());
// registerPcodeOpBehavior("SIMD_INT_ABS", new SIMD_INT_ABS());
// INT_ADD:
// registerPcodeOpBehavior("SIMD_INT_ADD", new SIMD_INT_ADD());
// registerPcodeOpBehavior("SIPD_INT_ADD", new SIPD_INT_ADD());
// INT_SUB:
registerPcodeOpBehavior("SIMD_INT_SUB", new SIMD_INT_SUB());
// registerPcodeOpBehavior("SIMD_INT_SUB", new SIMD_INT_SUB());
// INT_CARRY:
// INT_SCARRY:
// INT_SBORROW:
// INT_2COMP:
registerPcodeOpBehavior("SIMD_INT_2COMP", new SIMD_INT_2COMP());
// registerPcodeOpBehavior("SIMD_INT_2COMP", new SIMD_INT_2COMP());
// INT_NEGATE:
// registerPcodeOpBehavior("MP_INT_NEGATE", new MP_INT_NEGATE());
registerPcodeOpBehavior("SIMD_INT_NEGATE", new SIMD_INT_NEGATE());
// registerPcodeOpBehavior("SIMD_INT_NEGATE", new SIMD_INT_NEGATE());
// INT_XOR:
registerPcodeOpBehavior("SIMD_INT_XOR", new SIMD_INT_XOR());
// registerPcodeOpBehavior("SIMD_INT_XOR", new SIMD_INT_XOR());
// INT_AND:
// registerPcodeOpBehavior("MP_INT_AND", new MP_INT_AND());
registerPcodeOpBehavior("SIMD_INT_AND", new SIMD_INT_AND());
// registerPcodeOpBehavior("SIMD_INT_AND", new SIMD_INT_AND());
// INT_OR:
registerPcodeOpBehavior("SIMD_INT_OR", new SIMD_INT_OR());
// registerPcodeOpBehavior("SIMD_INT_OR", new SIMD_INT_OR());
// INT_LEFT:
registerPcodeOpBehavior("SIMD_INT_LEFT", new SIMD_INT_LEFT());
// registerPcodeOpBehavior("SIMD_INT_LEFT", new SIMD_INT_LEFT());
// INT_RIGHT:
registerPcodeOpBehavior("SIMD_INT_RIGHT", new SIMD_INT_RIGHT());
// registerPcodeOpBehavior("SIMD_INT_RIGHT", new SIMD_INT_RIGHT());
registerPcodeOpBehavior("MP_INT_RIGHT", new MP_INT_RIGHT());
// INT_SRIGHT:
registerPcodeOpBehavior("SIMD_INT_SRIGHT", new SIMD_INT_SRIGHT());
// registerPcodeOpBehavior("SIMD_INT_SRIGHT", new SIMD_INT_SRIGHT());
// INT_MULT:
registerPcodeOpBehavior("SIMD_INT_MULT", new SIMD_INT_MULT());
// registerPcodeOpBehavior("SIMD_INT_MULT", new SIMD_INT_MULT());
registerPcodeOpBehavior("MP_INT_MULT", new MP_INT_MULT());
registerPcodeOpBehavior("MP_INT_UMULT", new MP_INT_UMULT());
// INT_DIV:
@ -105,24 +105,24 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// UNUSED1:
// FLOAT_NAN:
// FLOAT_ADD:
registerPcodeOpBehavior("SIMD_FLOAT_ADD", new SIMD_FLOAT_ADD());
// registerPcodeOpBehavior("SIMD_FLOAT_ADD", new SIMD_FLOAT_ADD());
// registerPcodeOpBehavior("SIPD_FLOAT_ADD", new SIPD_FLOAT_ADD());
// FLOAT_DIV:
registerPcodeOpBehavior("SIMD_FLOAT_DIV", new SIMD_FLOAT_DIV());
// registerPcodeOpBehavior("SIMD_FLOAT_DIV", new SIMD_FLOAT_DIV());
// FLOAT_MULT:
registerPcodeOpBehavior("SIMD_FLOAT_MULT", new SIMD_FLOAT_MULT());
// registerPcodeOpBehavior("SIMD_FLOAT_MULT", new SIMD_FLOAT_MULT());
// FLOAT_SUB:
registerPcodeOpBehavior("SIMD_FLOAT_SUB", new SIMD_FLOAT_SUB());
// registerPcodeOpBehavior("SIMD_FLOAT_SUB", new SIMD_FLOAT_SUB());
// FLOAT_NEG:
registerPcodeOpBehavior("SIMD_FLOAT_NEG", new SIMD_FLOAT_NEG());
// registerPcodeOpBehavior("SIMD_FLOAT_NEG", new SIMD_FLOAT_NEG());
// FLOAT_ABS:
registerPcodeOpBehavior("SIMD_FLOAT_ABS", new SIMD_FLOAT_ABS());
// registerPcodeOpBehavior("SIMD_FLOAT_ABS", new SIMD_FLOAT_ABS());
// FLOAT_SQRT:
// INT2FLOAT:
// FLOAT2FLOAT:
registerPcodeOpBehavior("SIMD_FLOAT2FLOAT", new SIMD_FLOAT2FLOAT());
// registerPcodeOpBehavior("SIMD_FLOAT2FLOAT", new SIMD_FLOAT2FLOAT());
// TRUNC:
registerPcodeOpBehavior("SIMD_TRUNC", new SIMD_TRUNC());
// registerPcodeOpBehavior("SIMD_TRUNC", new SIMD_TRUNC());
// CEIL:
// FLOOR:
// ROUND:
@ -153,7 +153,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
private long getmask(long esize) {
long mask = -1;
if (esize < 8) mask = mask >>> ((8 - esize) * 8);
if (esize < 8) {
mask = mask >>> ((8 - esize) * 8);
}
return mask;
}
@ -182,7 +184,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// the byte array is in big endian order
protected long bytes_to_long(byte[] bytes, int lsb, int esize) {
if (lsb <= 0) return 0;
if (lsb <= 0) {
return 0;
}
int i = lsb - esize;
if (i < 0) {
@ -203,7 +207,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// array.
protected void insert_long(long value, byte[] outBytes, int lsb, int esize) {
if (lsb - esize < 0) throw new LowlevelError("insert_long: byte array too small");
if (lsb - esize < 0) {
throw new LowlevelError("insert_long: byte array too small");
}
for (int j = 0; j < esize; j++) {
outBytes[lsb - j - 1] = (byte) (value & 0xff);
value = value >> 8;
@ -218,7 +224,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
protected byte[] varnode_to_bytes(Varnode outputVarnode, byte[] initBytes, int esize) {
byte[] outBytes = new byte[outputVarnode.getSize()];
if (initBytes == null) return outBytes;
if (initBytes == null) {
return outBytes;
}
byte ext = 0;
@ -228,7 +236,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
ext = (byte) ((initBytes[j - 1] >= 0) ? 0 : 0xff);
} else {
outBytes[i - 1] = ext;
if (((i - 1) % esize) == 0) break;
if (((i - 1) % esize) == 0) {
break;
}
}
}
@ -256,9 +266,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// Requires 1 input
int numArgs = inputs.length - 1;
if (numArgs != 2) throw new LowlevelError(this.getClass().getName() + ": requires 2 inputs (op, size), got " + numArgs);
if (numArgs != 2) {
throw new LowlevelError(this.getClass().getName() + ": requires 2 inputs (op, size), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError(this.getClass().getName() + ": missing required output");
if (outputVarnode == null) {
throw new LowlevelError(this.getClass().getName() + ": missing required output");
}
MemoryState memoryState = emu.getMemoryState();
@ -267,16 +281,19 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
Varnode simdVarnode = inputs[1];
int esize = (int) memoryState.getValue(inputs[2]);
if (outputVarnode.getSize() < simdVarnode.getSize())
if (outputVarnode.getSize() < simdVarnode.getSize()) {
throw new LowlevelError(this.getClass().getName() + ": input size (" + simdVarnode.getSize()
+ ") exceeds output size (" + outputVarnode.getSize() + ")");
}
if (esize != 1 && esize != 2 && esize != 4 && esize != 8)
if (esize != 1 && esize != 2 && esize != 4 && esize != 8) {
throw new LowlevelError(this.getClass().getName() + ": operand must be 1, 2, 4, or 8 bytes: got " + esize);
}
if ((outputVarnode.getSize() % esize) != 0)
if ((outputVarnode.getSize() % esize) != 0) {
throw new LowlevelError(this.getClass().getName() + ": output size (" + outputVarnode.getSize()
+ ") must be a multiple of operand size (" + esize + ")");
}
}
}
@ -516,9 +533,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// Requires 2 or 3 inputs
int numArgs = inputs.length - 1;
if (numArgs != 2 && numArgs != 3) throw new LowlevelError(this.getClass().getName() + ": requires 3 inputs (simd, op, esize), got " + numArgs);
if (numArgs != 2 && numArgs != 3) {
throw new LowlevelError(this.getClass().getName() + ": requires 3 inputs (simd, op, esize), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError(this.getClass().getName() + ": missing required output");
if (outputVarnode == null) {
throw new LowlevelError(this.getClass().getName() + ": missing required output");
}
MemoryState memoryState = emu.getMemoryState();
@ -529,23 +550,28 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
int esize = opVarnode.getSize();
boolean opConstant = (numArgs == 2);
if (! opConstant)
if (! opConstant) {
esize = (int) memoryState.getValue(inputs[3]);
}
if (outputVarnode.getSize() < simdVarnode.getSize())
if (outputVarnode.getSize() < simdVarnode.getSize()) {
throw new LowlevelError(this.getClass().getName() + ": input size (" + simdVarnode.getSize()
+ ") exceeds output size (" + outputVarnode.getSize() + ")");
}
if (esize != 1 && esize != 2 && esize != 4 && esize != 8)
if (esize != 1 && esize != 2 && esize != 4 && esize != 8) {
throw new LowlevelError(this.getClass().getName() + ": operand must be 1, 2, 4, or 8 bytes: got " + esize);
}
if ((outputVarnode.getSize() % esize) != 0)
if ((outputVarnode.getSize() % esize) != 0) {
throw new LowlevelError(this.getClass().getName() + ": output size (" + outputVarnode.getSize()
+ ") must be a multiple of operand size (" + esize + ")");
}
if (! opConstant && simdVarnode.getSize() != opVarnode.getSize())
if (! opConstant && simdVarnode.getSize() != opVarnode.getSize()) {
throw new LowlevelError(this.getClass().getName() + ": simd size (" + outputVarnode.getSize()
+ ") and operand size (" + esize + ") must be the same for simd operation");
}
}
}
@ -565,7 +591,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
Varnode opVarnode = inputs[2];
boolean opConstant = (inputs.length == 3);
int esize = opVarnode.getSize();
if (! opConstant) esize = (int) memoryState.getValue(inputs[3]);
if (! opConstant) {
esize = (int) memoryState.getValue(inputs[3]);
}
int opstep = (opConstant ? 0 : esize);
byte[] simdBytes = memoryState.getBigInteger(simdVarnode, true).toByteArray();
@ -607,7 +635,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
Varnode opVarnode = inputs[2];
boolean opConstant = (inputs.length == 3);
int esize = opVarnode.getSize();
if (! opConstant) esize = (int) memoryState.getValue(inputs[3]);
if (! opConstant) {
esize = (int) memoryState.getValue(inputs[3]);
}
int opstep = (opConstant ? 0 : esize);
byte[] simdBytes = memoryState.getBigInteger(simdVarnode, false).toByteArray();
@ -653,9 +683,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// Requires 2 inputs
int numArgs = inputs.length - 1;
if (numArgs != 2 && numArgs != 3) throw new LowlevelError(this.getClass().getName() + ": requires 2 or 3 inputs (pairData*, esize), got " + numArgs);
if (numArgs != 2 && numArgs != 3) {
throw new LowlevelError(this.getClass().getName() + ": requires 2 or 3 inputs (pairData*, esize), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError(this.getClass().getName() + ": missing required output");
if (outputVarnode == null) {
throw new LowlevelError(this.getClass().getName() + ": missing required output");
}
MemoryState memoryState = emu.getMemoryState();
@ -673,11 +707,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
int osize = outputVarnode.getSize();
int oesize = (iesize * osize) / isize;
if (iesize != 1 && iesize != 2 && iesize != 4 && iesize != 8)
if (iesize != 1 && iesize != 2 && iesize != 4 && iesize != 8) {
throw new LowlevelError(this.getClass().getName() + ": operand lanes must be 1, 2, 4, or 8 bytes: got " + iesize);
}
if (oesize != 1 && oesize != 2 && oesize != 4 && oesize != 8)
if (oesize != 1 && oesize != 2 && oesize != 4 && oesize != 8) {
throw new LowlevelError(this.getClass().getName() + ": output lanes must be 1, 2, 4, or 8 bytes: got " + oesize);
}
}
}
@ -921,9 +957,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@Override
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
int numArgs = inputs.length - 1;
if (numArgs != 2) throw new LowlevelError("MP_INT_EQUAL: requires 2 (Vm, Vn), got " + numArgs);
if (numArgs != 2) {
throw new LowlevelError("MP_INT_EQUAL: requires 2 (Vm, Vn), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError("MP_INT_EQUAL: missing required output");
if (outputVarnode == null) {
throw new LowlevelError("MP_INT_EQUAL: missing required output");
}
MemoryState memoryState = emu.getMemoryState();
BigInteger cmp1 = memoryState.getBigInteger(inputs[1], false);
@ -956,9 +996,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@Override
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
int numArgs = inputs.length - 1;
if (numArgs != 1) throw new LowlevelError("MP_INT_ABS: requires 1 (Vn), got " + numArgs);
if (numArgs != 1) {
throw new LowlevelError("MP_INT_ABS: requires 1 (Vn), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError("MP_INT_ABS: missing required output");
if (outputVarnode == null) {
throw new LowlevelError("MP_INT_ABS: missing required output");
}
MemoryState memoryState = emu.getMemoryState();
BigInteger op = memoryState.getBigInteger(inputs[1], true);
@ -981,6 +1025,7 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@SuppressWarnings("unused")
private class SIPD_INT_ADD extends SIPD_SOP2 {
@Override
protected long op2(long x, long y, int iesize, int oesize) { return x + y; }
}
@ -1005,9 +1050,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@Override
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
int numArgs = inputs.length - 1;
if (numArgs != 1) throw new LowlevelError("MP_INT_NEGATE: requires 1 (Vn), got " + numArgs);
if (numArgs != 1) {
throw new LowlevelError("MP_INT_NEGATE: requires 1 (Vn), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError("MP_INT_NEGATE: missing required output");
if (outputVarnode == null) {
throw new LowlevelError("MP_INT_NEGATE: missing required output");
}
MemoryState memoryState = emu.getMemoryState();
byte[] value = memoryState.getBigInteger(inputs[1], true).toByteArray();
@ -1047,9 +1096,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@Override
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
int numArgs = inputs.length - 1;
if (numArgs != 2) throw new LowlevelError("MP_INT_AND: requires 2 (Vm, Vn), got " + numArgs);
if (numArgs != 2) {
throw new LowlevelError("MP_INT_AND: requires 2 (Vm, Vn), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError("MP_INT_AND: missing required output");
if (outputVarnode == null) {
throw new LowlevelError("MP_INT_AND: missing required output");
}
MemoryState memoryState = emu.getMemoryState();
BigInteger value = memoryState.getBigInteger(inputs[1], false);
@ -1094,9 +1147,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@Override
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
int numArgs = inputs.length - 1;
if (numArgs != 2) throw new LowlevelError("MP_INT_RIGHT: requires 2 (Vn, shift), got " + numArgs);
if (numArgs != 2) {
throw new LowlevelError("MP_INT_RIGHT: requires 2 (Vn, shift), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError("MP_INT_RIGHT: missing required output");
if (outputVarnode == null) {
throw new LowlevelError("MP_INT_RIGHT: missing required output");
}
MemoryState memoryState = emu.getMemoryState();
@ -1131,9 +1188,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@Override
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
int numArgs = inputs.length - 1;
if (numArgs != 2) throw new LowlevelError("MP_INT_MULT: requires 2 (Vm, Vn), got " + numArgs);
if (numArgs != 2) {
throw new LowlevelError("MP_INT_MULT: requires 2 (Vm, Vn), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError("MP_INT_MULT: missing required output");
if (outputVarnode == null) {
throw new LowlevelError("MP_INT_MULT: missing required output");
}
MemoryState memoryState = emu.getMemoryState();
BigInteger value = memoryState.getBigInteger(inputs[1], true);
@ -1157,9 +1218,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@Override
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
int numArgs = inputs.length - 1;
if (numArgs != 2) throw new LowlevelError("MP_INT_UMULT: requires 2 (Vm, Vn), got " + numArgs);
if (numArgs != 2) {
throw new LowlevelError("MP_INT_UMULT: requires 2 (Vm, Vn), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError("MP_INT_UMULT: missing required output");
if (outputVarnode == null) {
throw new LowlevelError("MP_INT_UMULT: missing required output");
}
MemoryState memoryState = emu.getMemoryState();
BigInteger value = memoryState.getBigInteger(inputs[1], false);
@ -1195,28 +1260,47 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@SuppressWarnings("unused")
private class SIPD_FLOAT_ADD extends SIPD_UOP2 {
@Override
protected long op2(long x, long y, int iesize, int oesize) {
if (iesize == 2) {
float fx = shortBitsToFloat(x);
float fy = shortBitsToFloat(y);
float fz = fx + fy;
if (oesize == 2) return floatToShortBits(fz);
if (oesize == 4) return (long) Float.floatToIntBits(fz);
if (oesize == 8) return Double.doubleToLongBits((double) fz);
if (oesize == 2) {
return floatToShortBits(fz);
}
if (oesize == 4) {
return (long) Float.floatToIntBits(fz);
}
if (oesize == 8) {
return Double.doubleToLongBits((double) fz);
}
} else if (iesize == 4) {
float fx = Float.intBitsToFloat((int) x);
float fy = Float.intBitsToFloat((int) y);
float fz = fx + fy;
if (oesize == 2) return floatToShortBits(fz);
if (oesize == 4) return (long) Float.floatToIntBits(fz);
if (oesize == 8) return Double.doubleToLongBits((double) fz);
if (oesize == 2) {
return floatToShortBits(fz);
}
if (oesize == 4) {
return (long) Float.floatToIntBits(fz);
}
if (oesize == 8) {
return Double.doubleToLongBits((double) fz);
}
} else if (iesize == 8) {
double fx = Double.longBitsToDouble(x);
double fy = Double.longBitsToDouble(y);
double fz = fx + fy;
if (oesize == 2) return floatToShortBits((float) fz);
if (oesize == 4) return (long) Float.floatToIntBits((float) fz);
if (oesize == 8) return Double.doubleToLongBits(fz);
if (oesize == 2) {
return floatToShortBits((float) fz);
}
if (oesize == 4) {
return (long) Float.floatToIntBits((float) fz);
}
if (oesize == 8) {
return Double.doubleToLongBits(fz);
}
}
return 0;
}
@ -1399,9 +1483,13 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// Requires 2 inputs
int numArgs = inputs.length - 1;
if (numArgs != 2) throw new LowlevelError("SIMD_PIECE: requires 2 inputs, got " + numArgs);
if (numArgs != 2) {
throw new LowlevelError("SIMD_PIECE: requires 2 inputs, got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError("SIMD_PIECE: missing required output");
if (outputVarnode == null) {
throw new LowlevelError("SIMD_PIECE: missing required output");
}
MemoryState memoryState = emu.getMemoryState();
@ -1410,9 +1498,10 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
Varnode simdVarnode = inputs[1];
int offset = (int) memoryState.getValue(inputs[2]);
if (simdVarnode.getSize() < (offset + 1) * outputVarnode.getSize())
if (simdVarnode.getSize() < (offset + 1) * outputVarnode.getSize()) {
throw new LowlevelError("SIMD_PIECE: input size (" + simdVarnode.getSize()
+ ") too small to extract output size (" + outputVarnode.getSize() + ") from offset (" + offset + ")");
}
// Allocate a byte array of the correct size to hold the output
// initialized to all zeros
@ -1453,8 +1542,12 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
@Override
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
int numArgs = inputs.length - 1;
if (numArgs != 2) throw new LowlevelError(this.getClass().getName() + ": requires 2 inputs (Vn, Vm), got " + numArgs);
if (outputVarnode == null) throw new LowlevelError(this.getClass().getName() + ": missing required output");
if (numArgs != 2) {
throw new LowlevelError(this.getClass().getName() + ": requires 2 inputs (Vn, Vm), got " + numArgs);
}
if (outputVarnode == null) {
throw new LowlevelError(this.getClass().getName() + ": missing required output");
}
MemoryState memoryState = emu.getMemoryState();
@ -1463,17 +1556,22 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
Varnode VnVarnode = inputs[1];
Varnode VmVarnode = inputs[2];
if (outSize != VnVarnode.getSize() + VmVarnode.getSize())
if (outSize != VnVarnode.getSize() + VmVarnode.getSize()) {
throw new LowlevelError(this.getClass().getName() + ": output size (" + outSize
+ ") must equal the sum of input sizes (" + VnVarnode.getSize() + "," + VmVarnode.getSize() + ")");
}
byte[] outBytes = new byte[outSize];
byte[] VnBytes = memoryState.getBigInteger(VnVarnode, false).toByteArray();
byte[] VmBytes = memoryState.getBigInteger(VmVarnode, false).toByteArray();
for (int i = outSize - 1, j = VnBytes.length - 1; i >= 0 && j >= 0; i--, j--) outBytes[i] = VnBytes[j];
for (int i = outSize - VnVarnode.getSize() - 1, j = VmBytes.length - 1; i >= 0 && j >= 0; i--, j--) outBytes[i] = VmBytes[j];
for (int i = outSize - 1, j = VnBytes.length - 1; i >= 0 && j >= 0; i--, j--) {
outBytes[i] = VnBytes[j];
}
for (int i = outSize - VnVarnode.getSize() - 1, j = VmBytes.length - 1; i >= 0 && j >= 0; i--, j--) {
outBytes[i] = VmBytes[j];
}
}
}
@ -1495,18 +1593,23 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
public void evaluate(Emulate emu, Varnode outputVarnode, Varnode[] inputs) {
int numArgs = inputs.length - 1;
if (numArgs < 3 || numArgs > 6) throw new LowlevelError("a64_TBL: requires 3 to 6 inputs (Vinit, Vn-Vn4, Vm), got " + numArgs);
if (numArgs < 3 || numArgs > 6) {
throw new LowlevelError("a64_TBL: requires 3 to 6 inputs (Vinit, Vn-Vn4, Vm), got " + numArgs);
}
if (outputVarnode == null) throw new LowlevelError("a64_TBL: missing required output");
if (outputVarnode == null) {
throw new LowlevelError("a64_TBL: missing required output");
}
MemoryState memoryState = emu.getMemoryState();
Varnode updateVarnode = inputs[1];
Varnode indexVarnode = inputs[numArgs];
// The index size must match the output size
if (outputVarnode.getSize() != indexVarnode.getSize())
if (outputVarnode.getSize() != indexVarnode.getSize()) {
throw new LowlevelError("a64_TBL: the output size (" + outputVarnode.getSize()
+ ") must match the index size (" + indexVarnode.getSize() + ")");
}
int regs = numArgs - 2;
int elements = outputVarnode.getSize();
@ -1514,8 +1617,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
// The indices are converted to little endian order
byte[] indices = new byte[elements];
byte[] vx = memoryState.getBigInteger(indexVarnode, false).toByteArray();
for (int j = 0; j < vx.length && j < elements; j++)
for (int j = 0; j < vx.length && j < elements; j++) {
indices[j] = vx[vx.length - j - 1];
}
// Create table from registers
// It consists of 16, 32, 48, or 64 bytes from Vn1-Vn4
@ -1526,8 +1630,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
byte[] table = new byte[64];
for (int i = 0; i < regs; i++) {
byte[] vn = memoryState.getBigInteger(inputs[2 + i], false).toByteArray();
for (int j = 0; j < vn.length && i * 16 + j < 64; j++)
for (int j = 0; j < vn.length && i * 16 + j < 64; j++) {
table[i*16 + j] = vn[vn.length - j - 1];
}
}
// The result is pre-initialized to Vi
@ -1536,8 +1641,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
byte[] result = new byte[elements];
byte[] vi = memoryState.getBigInteger(updateVarnode, false).toByteArray();
for (int j = 0; j < vi.length && j < elements; j++)
for (int j = 0; j < vi.length && j < elements; j++) {
result[j] = vi[vi.length - j - 1];
}
// Since the indices, table, and result
// are all in little endian order
@ -1546,7 +1652,9 @@ public class AARCH64EmulateInstructionStateModifier extends EmulateInstructionSt
for (int i = 0; i < elements; i++) {
int index = (int) (indices[i] & 0xff);
if (index < 16 * regs) result[i] = table[index];
if (index < 16 * regs) {
result[i] = table[index];
}
}
// reverse the endianness of the result, in place

View File

@ -25,9 +25,9 @@
<div class="titlepage">
<div>
<div><h1 class="title">
<a name="idm140016193433872"></a>SLEIGH</h1></div>
<a name="idm140526921073488"></a>SLEIGH</h1></div>
<div><h3 class="subtitle"><i>A Language for Rapid Processor Specification</i></h3></div>
<div><p class="releaseinfo">Last updated September 5, 2019</p></div>
<div><p class="releaseinfo">Last updated October 28, 2020</p></div>
<div><p class="pubdate">Originally published December 16, 2005</p></div>
</div>
<hr>
@ -35,51 +35,51 @@
<div class="toc">
<p><b>Table of Contents</b></p>
<dl class="toc">
<dt><span class="sect1"><a href="sleigh.html#idm140016193411168">1. Introduction to P-Code</a></span></dt>
<dt><span class="sect1"><a href="sleigh.html#idm140526921048752">1. Introduction to P-Code</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="sleigh.html#idm140016193402816">1.1. Address Spaces</a></span></dt>
<dt><span class="sect2"><a href="sleigh.html#idm140526921040400">1.1. Address Spaces</a></span></dt>
<dt><span class="sect2"><a href="sleigh.html#sleigh_varnodes">1.2. Varnodes</a></span></dt>
<dt><span class="sect2"><a href="sleigh.html#idm140016193387168">1.3. Operations</a></span></dt>
<dt><span class="sect2"><a href="sleigh.html#idm140526921024752">1.3. Operations</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="sleigh_layout.html">2. Basic Specification Layout</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140016193347968">2.1. Comments</a></span></dt>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140016193345328">2.2. Identifiers</a></span></dt>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140016193343696">2.3. Strings</a></span></dt>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140016193341936">2.4. Integers</a></span></dt>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140016193337552">2.5. White Space</a></span></dt>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140526920986416">2.1. Comments</a></span></dt>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140526920983776">2.2. Identifiers</a></span></dt>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140526920982144">2.3. Strings</a></span></dt>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140526920980384">2.4. Integers</a></span></dt>
<dt><span class="sect2"><a href="sleigh_layout.html#idm140526920976000">2.5. White Space</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="sleigh_preprocessing.html">3. Preprocessing</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="sleigh_preprocessing.html#sleigh_including_files">3.1. Including Files</a></span></dt>
<dt><span class="sect2"><a href="sleigh_preprocessing.html#idm140016193329920">3.2. Preprocessor Macros</a></span></dt>
<dt><span class="sect2"><a href="sleigh_preprocessing.html#idm140016193323088">3.3. Conditional Compilation</a></span></dt>
<dt><span class="sect2"><a href="sleigh_preprocessing.html#idm140526920968368">3.2. Preprocessor Macros</a></span></dt>
<dt><span class="sect2"><a href="sleigh_preprocessing.html#idm140526920961536">3.3. Conditional Compilation</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="sleigh_definitions.html">4. Basic Definitions</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="sleigh_definitions.html#sleigh_endianess_definition">4.1. Endianess Definition</a></span></dt>
<dt><span class="sect2"><a href="sleigh_definitions.html#idm140016193284896">4.2. Alignment Definition</a></span></dt>
<dt><span class="sect2"><a href="sleigh_definitions.html#idm140016193281872">4.3. Space Definitions</a></span></dt>
<dt><span class="sect2"><a href="sleigh_definitions.html#idm140526921098128">4.2. Alignment Definition</a></span></dt>
<dt><span class="sect2"><a href="sleigh_definitions.html#idm140526921095104">4.3. Space Definitions</a></span></dt>
<dt><span class="sect2"><a href="sleigh_definitions.html#sleigh_naming_registers">4.4. Naming Registers</a></span></dt>
<dt><span class="sect2"><a href="sleigh_definitions.html#idm140016193245424">4.5. Bit Range Registers</a></span></dt>
<dt><span class="sect2"><a href="sleigh_definitions.html#idm140016193233216">4.6. User-Defined Operations</a></span></dt>
<dt><span class="sect2"><a href="sleigh_definitions.html#idm140526920875744">4.5. Bit Range Registers</a></span></dt>
<dt><span class="sect2"><a href="sleigh_definitions.html#idm140526920863712">4.6. User-Defined Operations</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="sleigh_symbols.html">5. Introduction to Symbols</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="sleigh_symbols.html#idm140016193206464">5.1. Notes on Namespaces</a></span></dt>
<dt><span class="sect2"><a href="sleigh_symbols.html#idm140526920845152">5.1. Notes on Namespaces</a></span></dt>
<dt><span class="sect2"><a href="sleigh_symbols.html#sleigh_predefined_symbols">5.2. Predefined Symbols</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="sleigh_tokens.html">6. Tokens and Fields</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="sleigh_tokens.html#sleigh_defining_tokens">6.1. Defining Tokens and Fields</a></span></dt>
<dt><span class="sect2"><a href="sleigh_tokens.html#idm140016193166064">6.2. Fields as Family Symbols</a></span></dt>
<dt><span class="sect2"><a href="sleigh_tokens.html#idm140016193160240">6.3. Attaching Alternate Meanings to Fields</a></span></dt>
<dt><span class="sect2"><a href="sleigh_tokens.html#idm140526920800080">6.2. Fields as Family Symbols</a></span></dt>
<dt><span class="sect2"><a href="sleigh_tokens.html#idm140526920794256">6.3. Attaching Alternate Meanings to Fields</a></span></dt>
<dt><span class="sect2"><a href="sleigh_tokens.html#sleigh_context_variables">6.4. Context Variables</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="sleigh_constructors.html">7. Constructors</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="sleigh_constructors.html#idm140016193117504">7.1. The Five Sections of a Constructor</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#idm140016193112928">7.2. The Table Header</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#idm140526920750848">7.1. The Five Sections of a Constructor</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#idm140526920746272">7.2. The Table Header</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#sleigh_display_section">7.3. The Display Section</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#sleigh_bit_pattern">7.4. The Bit Pattern Section</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#sleigh_disassembly_actions">7.5. Disassembly Actions Section</a></span></dt>
@ -87,12 +87,12 @@
<dt><span class="sect2"><a href="sleigh_constructors.html#sleigh_semantic_section">7.7. The Semantic Section</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#sleigh_tables">7.8. Tables</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#sleigh_macros">7.9. P-code Macros</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#idm140016192659536">7.10. Build Directives</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#idm140016192651168">7.11. Delay Slot Directives</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#idm140526920290640">7.10. Build Directives</a></span></dt>
<dt><span class="sect2"><a href="sleigh_constructors.html#idm140526920281024">7.11. Delay Slot Directives</a></span></dt>
</dl></dd>
<dt><span class="sect1"><a href="sleigh_context.html">8. Using Context</a></span></dt>
<dd><dl>
<dt><span class="sect2"><a href="sleigh_context.html#idm140016192630992">8.1. Basic Use of Context Variables</a></span></dt>
<dt><span class="sect2"><a href="sleigh_context.html#idm140526920261472">8.1. Basic Use of Context Variables</a></span></dt>
<dt><span class="sect2"><a href="sleigh_context.html#sleigh_local_change">8.2. Local Context Change</a></span></dt>
<dt><span class="sect2"><a href="sleigh_context.html#sleigh_global_change">8.3. Global Context Change</a></span></dt>
</dl></dd>
@ -101,7 +101,7 @@
</div>
<div class="simplesect">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="idm140016193435456"></a>History</h2></div></div></div>
<a name="idm140526921055904"></a>History</h2></div></div></div>
<p>
This document describes the syntax for the SLEIGH processor
specification language, which was developed for the GHIDRA
@ -129,7 +129,7 @@
</div>
<div class="simplesect">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="idm140016193415136"></a>Overview</h2></div></div></div>
<a name="idm140526921052720"></a>Overview</h2></div></div></div>
<p>
SLEIGH is a language for describing the instruction sets of general
purpose microprocessors, in order to facilitate the reverse
@ -162,7 +162,7 @@ Italics are used when defining terms and for named entities. Bold is used for SL
</div>
<div class="sect1">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="idm140016193411168"></a>1. Introduction to P-Code</h2></div></div></div>
<a name="idm140526921048752"></a>1. Introduction to P-Code</h2></div></div></div>
<p>
Although p-code is a distinct language from SLEIGH, because a major
purpose of SLEIGH is to specify the translation from machine code to
@ -221,7 +221,7 @@ respectively.
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193402816"></a>1.1. Address Spaces</h3></div></div></div>
<a name="idm140526921040400"></a>1.1. Address Spaces</h3></div></div></div>
<p>
An <span class="emphasis"><em>address</em></span> space for p-code is a generalization of
the indexed memory (RAM) that a typical processor has access to, and
@ -322,7 +322,7 @@ must be provided and enforced by the specification designer.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193387168"></a>1.3. Operations</h3></div></div></div>
<a name="idm140526921024752"></a>1.3. Operations</h3></div></div></div>
<p>
P-code is intended to emulate a target processor by substituting a
sequence of p-code operations for each machine instruction. Thus every

View File

@ -60,7 +60,7 @@ multiple constructors into a single table are addressed in <a class="xref" href=
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193117504"></a>7.1. The Five Sections of a Constructor</h3></div></div></div>
<a name="idm140526920750848"></a>7.1. The Five Sections of a Constructor</h3></div></div></div>
<p>
A single complex statement in the specification file describes a
constructor. This statement is always made up of five distinct
@ -92,7 +92,7 @@ in turn.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193112928"></a>7.2. The Table Header</h3></div></div></div>
<a name="idm140526920746272"></a>7.2. The Table Header</h3></div></div></div>
<p>
Every constructor must be part of a table, which is the element with
an actual family symbol identifier associated with it. So each
@ -230,7 +230,7 @@ no such requirement.
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193083344"></a>7.3.2. The '^' character</h4></div></div></div>
<a name="idm140526920716688"></a>7.3.2. The '^' character</h4></div></div></div>
<p>
The &#8216;^&#8217; character in the display section is used to separate
identifiers from other characters where there shouldn&#8217;t be white space
@ -278,7 +278,7 @@ to <span class="emphasis"><em>match</em></span> the constructor being defined.
</p>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193071904"></a>7.4.1. Constraints</h4></div></div></div>
<a name="idm140526920705248"></a>7.4.1. Constraints</h4></div></div></div>
<p>
The patterns required for processor specifications can almost always
be described as a mask and value pair. Given a specific instruction
@ -337,7 +337,7 @@ requires two or more mask/value style checks to correctly implement.
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193057968"></a>7.4.3. Defining Operands and Invoking Subtables</h4></div></div></div>
<a name="idm140526920691312"></a>7.4.3. Defining Operands and Invoking Subtables</h4></div></div></div>
<p>
The principle way of defining a constructor operand, left undefined
from the display section, is done in the bit pattern section. If an
@ -396,7 +396,7 @@ statement of the grouping of old symbols into the new constructor.
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193046560"></a>7.4.4. Variable Length Instructions</h4></div></div></div>
<a name="idm140526920679904"></a>7.4.4. Variable Length Instructions</h4></div></div></div>
<p>
There are some additional complexities to designing a specification
for a processor with variable length instructions. Some initial
@ -419,7 +419,7 @@ designer control over how tokens fit together.
</p>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016193043088"></a>7.4.4.1. The ';' Operator</h5></div></div></div>
<a name="idm140526920676432"></a>7.4.4.1. The ';' Operator</h5></div></div></div>
<p>
The most important operator for patterns defining variable length
instructions is the concatenation operator &#8216;;&#8217;. When building a
@ -481,7 +481,7 @@ operator, so parentheses may be necessary to get the intended meaning.
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016193027776"></a>7.4.4.2. The '...' Operator</h5></div></div></div>
<a name="idm140526920661120"></a>7.4.4.2. The '...' Operator</h5></div></div></div>
<p>
The ellipsis operator &#8216;...&#8217; is used to satisfy the token matching
requirements of the &#8216;&amp;&#8217; and &#8216;|&#8217; operators (described in the previous
@ -557,7 +557,7 @@ don&#8217;t quite match the assembly.
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193007488"></a>7.4.6. Empty Patterns</h4></div></div></div>
<a name="idm140526920640560"></a>7.4.6. Empty Patterns</h4></div></div></div>
<p>
Occasionally there is a need for an empty pattern when building
tables. An empty pattern matches everything. There is a predefined
@ -567,7 +567,7 @@ to indicate an empty pattern.
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193005648"></a>7.4.7. Advanced Constraints</h4></div></div></div>
<a name="idm140526920638720"></a>7.4.7. Advanced Constraints</h4></div></div></div>
<p>
A constraint does not have to be of the form &#8220;field = constant&#8221;,
although this is almost always what is needed. In certain situations,
@ -821,7 +821,7 @@ assignment to such a variable changes the context in which the current
instruction is being disassembled and can potentially have a drastic
effect on how the rest of the instruction is disassembled. An
assignment of this form is considered local to the instruction and
will not effect how other instructions are parsed. The context
will not affect how other instructions are parsed. The context
variable is reset to its original value before parsing other
instructions. The disassembly action may also contain one or
more <span class="bold"><strong>globalset</strong></span> directives, which
@ -939,7 +939,7 @@ varnode is <span class="emphasis"><em>r1</em></span>.
</p>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016192898096"></a>7.7.1. Expressions</h4></div></div></div>
<a name="idm140526920530304"></a>7.7.1. Expressions</h4></div></div></div>
<p>
Expressions are built out of symbols and the binary and unary
operators listed in <a class="xref" href="sleigh_ref.html#syntaxref.htmltable" title="Table 5. Semantic Expression Operators and Syntax">Table 5, &#8220;Semantic Expression Operators and Syntax&#8221;</a> in the
@ -954,7 +954,7 @@ within expressions to affect this order.
</p>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192895760"></a>7.7.1.1. Arithmetic, Logical and Boolean Operators</h5></div></div></div>
<a name="idm140526920527872"></a>7.7.1.1. Arithmetic, Logical and Boolean Operators</h5></div></div></div>
<p>
For the most part these operators should be familiar to software
developers. The only real differences arise from the fact that
@ -1017,7 +1017,7 @@ set to something other than one.
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192883312"></a>7.7.1.3. Extension</h5></div></div></div>
<a name="idm140526920515552"></a>7.7.1.3. Extension</h5></div></div></div>
<p>
Most processors have instructions that extend small values into big
values, and many instructions do these minor data manipulations
@ -1039,7 +1039,7 @@ the <span class="bold"><strong>sext</strong></span> operator.
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192876752"></a>7.7.1.4. Truncation</h5></div></div></div>
<a name="idm140526920508832"></a>7.7.1.4. Truncation</h5></div></div></div>
<p>
There are two forms of syntax indicating a truncation of the input
varnode. In one the varnode is followed by a colon &#8216;:&#8217; and an integer
@ -1169,7 +1169,7 @@ the offset portion of the address, and to copy the desired value, the
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192851952"></a>7.7.1.7. Managed Code Operations</h5></div></div></div>
<a name="idm140526920484032"></a>7.7.1.7. Managed Code Operations</h5></div></div></div>
<p>
SLEIGH provides basic support for instructions where encoding and context
don't provide a complete description of the semantics. This is the case
@ -1231,7 +1231,7 @@ define pcodeop arctan;
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016192839392"></a>7.7.2. Statements</h4></div></div></div>
<a name="idm140526920471120"></a>7.7.2. Statements</h4></div></div></div>
<p>
We describe the types of semantic statements that are allowed in SLEIGH.
</p>
@ -1305,7 +1305,7 @@ and may be enforced in future compiler versions.
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192826448"></a>7.7.2.2. Storage Statements</h5></div></div></div>
<a name="idm140526920458176"></a>7.7.2.2. Storage Statements</h5></div></div></div>
<p>
SLEIGH supports fairly standard <span class="emphasis"><em>storage statement</em></span>
syntax to complement the load operator. The left-hand side of an
@ -1336,7 +1336,7 @@ attribute is set to something other than one.
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192820512"></a>7.7.2.3. Exports</h5></div></div></div>
<a name="idm140526920452240"></a>7.7.2.3. Exports</h5></div></div></div>
<p>
The semantic section doesn&#8217;t just specify how to generate p-code for a
constructor. Except for those constructors in the root table, this
@ -1366,7 +1366,7 @@ the table symbol <span class="emphasis"><em>mode</em></span>. When this construc
matched, as part of a more complicated instruction, the
symbol <span class="emphasis"><em>mode</em></span> will represent the original semantic
value of <span class="emphasis"><em>reg</em></span> but with the standard post-increment
side effect.
side-effect.
</p>
<p>
The table symbol associated with the constructor becomes
@ -1388,7 +1388,7 @@ varnode being modified to be exported as an integer constant.
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192809280"></a>7.7.2.4. Dynamic References</h5></div></div></div>
<a name="idm140526920441008"></a>7.7.2.4. Dynamic References</h5></div></div></div>
<p>
The only other operator allowed as part of
an <span class="bold"><strong>export</strong></span> statement, is the &#8216;*&#8217;
@ -1447,7 +1447,7 @@ levels.
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192795680"></a>7.7.2.5. Branching Statements</h5></div></div></div>
<a name="idm140526920427360"></a>7.7.2.5. Branching Statements</h5></div></div></div>
<p>
This section discusses statements that generate p-code branching
operations. These are listed in <a class="xref" href="sleigh_ref.html#branchref.htmltable" title="Table 7. Branching Statements">Table 7, &#8220;Branching Statements&#8221;</a>, in the Appendix.
@ -1802,7 +1802,7 @@ each followed by a variation which corrects the error.
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016192728656"></a>7.7.4. Unimplemented Semantics</h4></div></div></div>
<a name="idm140526920360336"></a>7.7.4. Unimplemented Semantics</h4></div></div></div>
<p>
The semantic section must be present for every constructor in the
specification. But the designer can leave the semantics explicitly
@ -1962,7 +1962,7 @@ should generally be avoided.
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016192701504"></a>7.8.2. Specific Symbol Trees</h4></div></div></div>
<a name="idm140526920333184"></a>7.8.2. Specific Symbol Trees</h4></div></div></div>
<p>
When the SLEIGH parser analyzes an instruction, it starts with the
root symbol <span class="emphasis"><em>instruction</em></span>, and decides which of the
@ -2045,7 +2045,7 @@ and p-code for these encodings by walking the trees.
</p>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192682592"></a>7.8.2.1. Disassembly Trees</h5></div></div></div>
<a name="idm140526920314640"></a>7.8.2.1. Disassembly Trees</h5></div></div></div>
<p>
If the nodes of each tree are replaced with the display information of
the corresponding specific symbol, we see how the disassembly
@ -2068,7 +2068,7 @@ statements corresponding to the original instruction encodings.
</div>
<div class="sect4">
<div class="titlepage"><div><div><h5 class="title">
<a name="idm140016192676208"></a>7.8.2.2. P-code Trees</h5></div></div></div>
<a name="idm140526920308256"></a>7.8.2.2. P-code Trees</h5></div></div></div>
<p>
A similar procedure produces the resulting p-code translation of the
instruction. If each node in the specific symbol tree is replaced with
@ -2147,7 +2147,7 @@ directive however should not be used in a macro.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016192659536"></a>7.10. Build Directives</h3></div></div></div>
<a name="idm140526920290640"></a>7.10. Build Directives</h3></div></div></div>
<p>
Because the nodes of a specific symbol tree are traversed in a
depth-first order, the p-code for a child node in general comes before
@ -2202,7 +2202,7 @@ normal action of the instruction.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016192651168"></a>7.11. Delay Slot Directives</h3></div></div></div>
<a name="idm140526920281024"></a>7.11. Delay Slot Directives</h3></div></div></div>
<p>
For processors with a pipe-lined architecture, multiple instructions
are typically executing simultaneously. This can lead to processor

View File

@ -85,7 +85,7 @@ whose encodings are otherwise the same.
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016192630992"></a>8.1. Basic Use of Context Variables</h3></div></div></div>
<a name="idm140526920261472"></a>8.1. Basic Use of Context Variables</h3></div></div></div>
<p>
Suppose a processor supports the use of two different sets of
registers in its main addressing mode, based on the setting of a
@ -317,7 +317,7 @@ blr is opcode=35 &amp; reg=15 &amp; LRset=1 { return [lr]; }
An alternative to the <span class="bold"><strong>noflow</strong></span> attribute is to simply issue
multiple directives within a single constructor, so an explicit end to a context change
can be given. The value of the variable exported to the global state
is the one in affect at the point where the directive is issued. Thus,
is the one in effect at the point where the directive is issued. Thus,
after one <span class="bold"><strong>globalset</strong></span>, the same context
variable can be assigned a different value, followed by
another <span class="bold"><strong>globalset</strong></span> for a different
@ -328,7 +328,7 @@ Because context in SLEIGH is controlled by a disassembly process,
there are some basic caveats to the use of
the <span class="bold"><strong>globalset</strong></span> directive. With
<span class="emphasis"><em>flowing</em></span> context changes,
there is no guarantee of what global state will be in affect at a
there is no guarantee of what global state will be in effect at a
particular address. During disassembly, at any given
point, the process may not have uncovered all the relevant directives,
and the known directives may not necessarily be consistent. In

View File

@ -44,18 +44,19 @@ define endian=little;
</pre></div>
<p>
This defines how the processor interprets contiguous sequences of
bytes as integers. It effects how integer fields within an instruction
are interpreted (see <a class="xref" href="sleigh_tokens.html#sleigh_defining_tokens" title="6.1. Defining Tokens and Fields">Section 6.1, &#8220;Defining Tokens and Fields&#8221;</a>), and
it also effects the details of how the processor is supposed to
implement atomic operations like integer addition and integer
compare. The specification designer should only need to worry about
these details when labeling instruction fields, otherwise the
specification language will hide endianess issues.
bytes as integers or other values and globally affects values across
all address spaces. It also affects how integer fields
within an instruction are interpreted, (see <a class="xref" href="sleigh_tokens.html#sleigh_defining_tokens" title="6.1. Defining Tokens and Fields">Section 6.1, &#8220;Defining Tokens and Fields&#8221;</a>),
although it is possible to override this setting in the rare case that endianess is
different for data versus instruction encoding.
The specification designer generally only needs to worry about
endianess when labeling instruction fields and when defining overlapping registers,
otherwise the specification language hides endianess issues.
</p>
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193284896"></a>4.2. Alignment Definition</h3></div></div></div>
<a name="idm140526921098128"></a>4.2. Alignment Definition</h3></div></div></div>
<p>
An alignment definition looks like
</p>
@ -72,7 +73,7 @@ instruction as an error.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193281872"></a>4.3. Space Definitions</h3></div></div></div>
<a name="idm140526921095104"></a>4.3. Space Definitions</h3></div></div></div>
<p>
The definition of an address space looks like
</p>
@ -227,7 +228,7 @@ define register offset=0 size=1
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193245424"></a>4.5. Bit Range Registers</h3></div></div></div>
<a name="idm140526920875744"></a>4.5. Bit Range Registers</h3></div></div></div>
<p>
Many processors define registers that either consist of a single bit
or otherwise don't use an integral number of bytes. A recurring
@ -298,7 +299,7 @@ used as an alternate syntax for defining overlapping registers.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193233216"></a>4.6. User-Defined Operations</h3></div></div></div>
<a name="idm140526920863712"></a>4.6. User-Defined Operations</h3></div></div></div>
<p>
The specification designer can define new p-code operations using
a <span class="bold"><strong>define pcodeop</strong></span> statement. This

View File

@ -36,7 +36,7 @@ by the compiler.
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193347968"></a>2.1. Comments</h3></div></div></div>
<a name="idm140526920986416"></a>2.1. Comments</h3></div></div></div>
<p>
Comments start with the &#8216;#&#8217; character and continue to the end of the
line. Comments can appear anywhere except the <span class="emphasis"><em>display section</em></span> of a
@ -46,7 +46,7 @@ interpreted as something that should be printed in disassembly.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193345328"></a>2.2. Identifiers</h3></div></div></div>
<a name="idm140526920983776"></a>2.2. Identifiers</h3></div></div></div>
<p>
Identifiers are made up of letters a-z, capitals A-Z, digits 0-9 and
the characters &#8216;.&#8217; and &#8216;_&#8217;. An identifier can use these characters in
@ -55,7 +55,7 @@ any order and for any length, but it must not start with a digit.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193343696"></a>2.3. Strings</h3></div></div></div>
<a name="idm140526920982144"></a>2.3. Strings</h3></div></div></div>
<p>
String literals can be used, when specifying names and when specifying
how disassembly should be printed, so that special characters are
@ -66,7 +66,7 @@ meaning.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193341936"></a>2.4. Integers</h3></div></div></div>
<a name="idm140526920980384"></a>2.4. Integers</h3></div></div></div>
<p>
Integers are specified either in a decimal format or in a standard
<span class="emphasis"><em>C-style</em></span> hexadecimal format by prepending the
@ -92,7 +92,7 @@ integers internally with 64 bits of precision.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193337552"></a>2.5. White Space</h3></div></div></div>
<a name="idm140526920976000"></a>2.5. White Space</h3></div></div></div>
<p>
White space characters include space, tab, line-feed, vertical
line-feed, and carriage-return (&#8216; &#8216;, &#8216;\t&#8217;, &#8216;\r&#8217;, &#8216;\v&#8217;,

View File

@ -54,7 +54,7 @@ own <span class="bold"><strong>@include</strong></span> directives.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193329920"></a>3.2. Preprocessor Macros</h3></div></div></div>
<a name="idm140526920968368"></a>3.2. Preprocessor Macros</h3></div></div></div>
<p>
SLEIGH allows simple (unparameterized) macro definitions and
expansions. A macro definition occurs on one line and starts with
@ -85,7 +85,7 @@ definition of a macro from that point on in the file.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193323088"></a>3.3. Conditional Compilation</h3></div></div></div>
<a name="idm140526920961536"></a>3.3. Conditional Compilation</h3></div></div></div>
<p>
SLEIGH supports several directives that allow conditional inclusion of
parts of a specification, based on the existence of a macro, or its
@ -103,7 +103,7 @@ and <span class="bold"><strong>@endif</strong></span>.
</p>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193316944"></a>3.3.1. @ifdef and @ifndef</h4></div></div></div>
<a name="idm140526920955392"></a>3.3.1. @ifdef and @ifndef</h4></div></div></div>
<p>
The <span class="bold"><strong>@ifdef</strong></span> directive is followed by a
macro identifier and evaluates to true if the macro is defined.
@ -129,7 +129,7 @@ or <span class="bold"><strong>@elif</strong></span> directive (See below).
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193310672"></a>3.3.2. @if</h4></div></div></div>
<a name="idm140526920949120"></a>3.3.2. @if</h4></div></div></div>
<p>
The <span class="bold"><strong>@if</strong></span> directive is followed by a
boolean expression with macros as the variables and strings as the
@ -158,7 +158,7 @@ is defined.
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193303584"></a>3.3.3. @else and @elif</h4></div></div></div>
<a name="idm140526920942032"></a>3.3.3. @else and @elif</h4></div></div></div>
<p>
An <span class="bold"><strong>@else</strong></span> directive splits the lines
bounded by an <span class="bold"><strong>@if</strong></span> directive and

View File

@ -105,7 +105,7 @@ the predefined identifier <span class="emphasis"><em>instruction</em></span>.
</p>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193206464"></a>5.1. Notes on Namespaces</h3></div></div></div>
<a name="idm140526920845152"></a>5.1. Notes on Namespaces</h3></div></div></div>
<p>
Almost all identifiers live in the same global "scope". The global scope includes
</p>
@ -138,7 +138,7 @@ individual <span class="emphasis"><em>constructor</em></span> (defined in <a cla
defines a local scope for operand names. As with most languages, a
local symbol with the same name as a global
symbol <span class="emphasis"><em>hides</em></span> the global symbol while that scope
is in affect.
is in effect.
</p>
</div>
<div class="sect2">

View File

@ -56,8 +56,22 @@ there are one or more field declarations specifying the name of the
field and the range of bits within the token making up the field. The
size of a field does <span class="emphasis"><em>not</em></span> need to be a multiple of
8. The range is inclusive where the least significant bit in the token
is labeled 0. The endianess of the processor will effect this labeling
when defining tokens that are bigger than 1 byte. After each field
is labeled 0. When defining tokens that are bigger than 1 byte, the
global endianess setting (See <a class="xref" href="sleigh_definitions.html#sleigh_endianess_definition" title="4.1. Endianess Definition">Section 4.1, &#8220;Endianess Definition&#8221;</a>)
will affect this labeling. Although it is rarely required, it is possible to override
the global endianess setting for a specific token by appending either the qualifier
<span class="bold"><strong>endian=little</strong></span> or <span class="bold"><strong>endian=big</strong></span>
immediately after the token name and size. For instance:
</p>
<div class="informalexample"><pre class="programlisting">
define token instr ( 32 ) endian=little op0=(0,15) <span class="weak">...</span>
</pre></div>
<p>
The token <span class="emphasis"><em>instr</em></span> is overridden to be little endian.
This override applies to all fields defined for the token but affects no other tokens.
</p>
<p>
After each field
declaration, there can be zero or more of the following attribute
keywords:
</p>
@ -74,7 +88,7 @@ different names.
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193166064"></a>6.2. Fields as Family Symbols</h3></div></div></div>
<a name="idm140526920800080"></a>6.2. Fields as Family Symbols</h3></div></div></div>
<p>
Fields are the most basic form of family symbol; they define a natural
map from instruction bits to a specific symbol as follows. We take the
@ -99,7 +113,7 @@ the <span class="bold"><strong>dec</strong></span> attribute is not supported]
</div>
<div class="sect2">
<div class="titlepage"><div><div><h3 class="title">
<a name="idm140016193160240"></a>6.3. Attaching Alternate Meanings to Fields</h3></div></div></div>
<a name="idm140526920794256"></a>6.3. Attaching Alternate Meanings to Fields</h3></div></div></div>
<p>
The default interpretation of a field is probably the most natural but
of course processors interpret fields within an instruction in a wide
@ -110,7 +124,7 @@ interpretations must be built up out of tables.
</p>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193158096"></a>6.3.1. Attaching Registers</h4></div></div></div>
<a name="idm140526920792112"></a>6.3.1. Attaching Registers</h4></div></div></div>
<p>
Probably <span class="emphasis"><em>the</em></span> most common processor interpretation
of a field is as an encoding of a particular register. In SLEIGH this
@ -149,7 +163,7 @@ of the instruction.
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193149824"></a>6.3.2. Attaching Other Integers</h4></div></div></div>
<a name="idm140526920783840"></a>6.3.2. Attaching Other Integers</h4></div></div></div>
<p>
Sometimes a processor interprets a field as an integer but not the
integer given by the default interpretation. A different integer
@ -171,7 +185,7 @@ unspecified positions in the list using a &#8216;_&#8217;]
</div>
<div class="sect3">
<div class="titlepage"><div><div><h4 class="title">
<a name="idm140016193144192"></a>6.3.3. Attaching Names</h4></div></div></div>
<a name="idm140526920778208"></a>6.3.3. Attaching Names</h4></div></div></div>
<p>
It is possible to just modify the display characteristics of a field
without changing the semantic meaning. The need for this is rare, but