mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 12:11:55 +00:00
Merge remote-tracking branch 'origin/GP-343_AARCH64neon' into Ghidra_9.2
This commit is contained in:
commit
d3950946e6
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
;
|
||||
|
@ -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); }
|
||||
|
@ -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 & reg=15 & 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
|
||||
|
@ -119,6 +119,7 @@ tokens {
|
||||
OP_SUBTABLE;
|
||||
OP_TABLE;
|
||||
OP_TOKEN;
|
||||
OP_TOKEN_ENDIAN;
|
||||
OP_TRUNCATION_SIZE;
|
||||
OP_TYPE;
|
||||
OP_UNIMPL;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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"));
|
||||
|
@ -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);
|
||||
|
@ -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 = ® + elem * esize;
|
||||
@else
|
||||
dest = ® + 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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ‘^’ character in the display section is used to separate
|
||||
identifiers from other characters where there shouldn’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 ‘;’. 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 ‘...’ is used to satisfy the token matching
|
||||
requirements of the ‘&’ and ‘|’ operators (described in the previous
|
||||
@ -557,7 +557,7 @@ don’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 “field = constant”,
|
||||
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, “Semantic Expression Operators and Syntax”</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 ‘:’ 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’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 ‘*’
|
||||
@ -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, “Branching Statements”</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
|
||||
|
@ -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 & reg=15 & 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
|
||||
|
@ -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, “Defining Tokens and Fields”</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, “Defining Tokens and Fields”</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
|
||||
|
@ -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 ‘#’ 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 ‘.’ and ‘_’. 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 (‘ ‘, ‘\t’, ‘\r’, ‘\v’,
|
||||
|
@ -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
|
||||
|
@ -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">
|
||||
|
@ -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, “Endianess Definition”</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 ‘_’]
|
||||
</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
|
||||
|
Loading…
Reference in New Issue
Block a user