1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
start = statement [';'] $;
statement = 'if' expr0 'then' statement {'else' statement} |
"UNPREDICTABLE" |
"UNDEFINED" |
"NOT_PERMITTED" |
"NOP" | "nop" |
"SEE" whatever |
tuple '=' expr0 |
ident '=' 'if' expr0 'then' expr0 'else' expr0 |
expr0 '=' expr0;
# tuples
tuple = '(' ('-'|expr0) { ',' ('-'|expr0) }+ ')';
# could use kleen star here instead of alternative rule, but I don't
# want to get back empty closures
expr0 = expr1 {('EOR' | '+' | '-' | '&&' | '||') expr1}+ |
expr1;
expr1 = expr2 {('*'|'/'|'<<'|'>>'|'DIV'|'XOR') expr2}+ |
expr2 {('==' | '!=' | '<=' | '>=' | '<' | '>') expr2}+ |
expr2;
expr2 = func_call |
expr3;
expr3 = builtin_value |
sliceable |
(ident|number|bits) {':'(ident|number|bits)}* |
tuple |
'(' expr0 ')' |
'!' expr0;
number = /\d+/;
bits = /'[01]+'/;
ident = /[a-zA-Z][\.\w]*/;
whatever = /.*/;
# the variables that can have bit slices ... these are made separate
# because the intersect with the greater-than, less-than comparisons
sliceable = 'index_align<' number ':' number '>' |
'index_align<' number '>' |
'align<' number '>' |
'mask<' number '>' |
'imod<' number '>' |
'imm6<' number '>' |
'imm6<' number ':' number '>' |
'imm8<' number '>' |
'Vd<' number '>' |
'Vn<' number '>' |
'Vm<' number '>' |
'Vm<' number ':' number '>' |
'cc<' number '>' |
'cmode<' number '>' |
'cmode<' number ':' number '>';
builtin_value = 'TRUE' |
'FALSE' |
'registers<' (number|ident) '>' |
'list<' (number|ident) '>' |
'cond<' number ':' number '>' |
'cond<' expr0 '>' |
'SRType_LSL' | 'SRType_LSR' | 'SRType_ASR' | 'SRType_ROR' | 'SRType_RRX' |
'InstrSet_ThumbEE' |
'ARM_GRP_INVALID' | 'ARM_GRP_JUMP' | 'ARM_GRP_CRYPT' | 'ARM_GRP_DATABARRIER' | 'ARM_GRP_DIVIDE' | 'ARM_GRP_FPARMV8' | 'ARM_GRP_MULTPRO' | 'ARM_GRP_NEON' | 'ARM_GRP_T2EXTRACTPACK' | 'ARM_GRP_THUMB2DSP' | 'ARM_GRP_TRUSTZONE' | 'ARM_GRP_V4T' | 'ARM_GRP_V5T' | 'ARM_GRP_V5TE' | 'ARM_GRP_V6' | 'ARM_GRP_V6T2' | 'ARM_GRP_V7' | 'ARM_GRP_V8' | 'ARM_GRP_VFP2' | 'ARM_GRP_VFP3' | 'ARM_GRP_VFP4' | 'ARM_GRP_ARM' | 'ARM_GRP_MCLASS' | 'ARM_GRP_NOTMCLASS' | 'ARM_GRP_THUMB' | 'ARM_GRP_THUMB1ONLY' | 'ARM_GRP_THUMB2' | 'ARM_GRP_PREV8' | 'ARM_GRP_FPVMLX' | 'ARM_GRP_MULOPS' | 'ARM_GRP_CRC' | 'ARM_GRP_DPVFP' | 'ARM_GRP_V6M';
# function calls
func_call = bitcount | badreg | consistent | decodeimmshift | thumbexpandimm |
thumbexpandimm_c | advsimdexpandimm | vfpexpandimm | uint | zeroextend | zeros | initblock | lastinitblock |
archversion | currentinstrset | signextend | not | issecure;
bitcount = 'BitCount(' expr0 ')';
badreg = 'BadReg(' expr0 ')';
consistent = 'Consistent(' expr0 ')';
decodeimmshift = 'DecodeImmShift(' expr0 ',' expr0 ')';
thumbexpandimm = 'ThumbExpandImm(' expr0 ')';
thumbexpandimm_c = 'ThumbExpandImm_C(' expr0 ',' expr0 ')';
advsimdexpandimm = 'AdvSIMDExpandImm(' expr0 ',' expr0 ',' expr0 ',' expr0 ')';
vfpexpandimm = 'VFPExpandImm(' expr0 ',' expr0 ',' expr0 ')';
uint = 'UInt(' expr0 ')';
zeroextend = 'ZeroExtend(' expr0 ',' expr0 ')';
zeros = 'Zeros(' expr0 ')';
initblock = 'InITBlock()';
lastinitblock = 'LastInITBlock()';
archversion = 'ArchVersion()';
currentinstrset = 'CurrentInstrSet()';
signextend = 'SignExtend(' expr3 ', 32)';
not = 'NOT(' expr0 ')';
issecure = 'IsSecure()';
|