Fix load-elim bug for branching instructions going to the same block
[hiphop-php.git] / hphp / ppc64-asm / decoder-ppc64.h
blobc5deff54b0c8a07655b7fda9fde3388f2ca35cf9
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | (c) Copyright IBM Corporation 2015-2016 |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_PPC64_ASM_DECODER_H_
18 #define incl_PPC64_ASM_DECODER_H_
20 #include <cstdint>
21 #include <string>
22 #include <deque>
23 #include <boost/noncopyable.hpp>
25 #include "hphp/ppc64-asm/isa-ppc64.h"
27 #include "hphp/util/assertions.h"
28 #include "hphp/util/portability.h"
30 namespace ppc64_asm {
32 // Mask to extract the instruction opcode
33 const PPC64Instr kOpcodeMask = 0xfc000000;
35 // Mask to remove the instruction opcode
36 const PPC64Instr kOperandMask = 0x03ffffff;
38 // decoder size is the next prime number from the table size
39 // decoder table is a hash table and this avoids some collisions, it's not
40 // the better way to do this but it's simple.
41 const size_t kDecoderSize = 211;
43 // Instruction type decoder masks
44 // The masks are sorted by number of bits needed to decode the instruction
45 // from more to less bits. Notice that some of those masks overlap instruction
46 // type so the table must be ordered in a way that return the
47 // correct instruction because the decoder will return the first exact match.
49 // TODO(rcardoso): Check those mask and create a better format so we can
50 // change those names to something more readable like: kXOFormMask, kXFXForm...
52 // EVX-FORM or EVS-FORM or VX-FORM [OP:6 XO:11]
53 const PPC64Instr kDecoderMask1 = (0x3F << 26) | (0x7FF);
54 // XFX-FORM [OP:6 [0x0 | 0x1] XO:10]
55 const PPC64Instr kDecoderMask2 = (0x3F << 26) | (0x3FF << 1) | (0x1 << 20);
56 // X-FORM or XL-FORM or XX1-FORM or X22-FORM or XFL-FORM
57 // [OP:6 XO:10 [EH:1|Rc:1|LK:1]]
58 const PPC64Instr kDecoderMask3 = (0x3F << 26) | (0x3FF << 1) | (0x1);
59 // VC-FORM [OP:6 Rc:1 XO:10]
60 const PPC64Instr kDecoderMask4 = (0x3F << 26) | (0x3FF) | (0x1 << 10);
61 // XX1-FORM or XFX-FORM [OP:6 XO:10]
62 const PPC64Instr kDecoderMask5 = (0x3F << 26) | (0x3FF << 1);
63 // Z22-FORM or XS-FORM [OP:6 XO:10 Rc:1]
64 const PPC64Instr kDecoderMask6 = (0x3F << 26) | (0x1FF << 1) | (0x1);
65 // XX2-FORM [OP:6 XO:9]
66 const PPC64Instr kDecoderMask7 = (0x3F << 26) | (0x1FF << 2);
67 // Z23-FORM or XO-FORM [OP:6 XO:9 Rc:1]
68 const PPC64Instr kDecoderMask8 = (0x3F << 26) | (0xFF << 1) | (0x1);
69 // TODO(rcardoso): check if this mask is correct
70 // XX3-FORM [OP:6 XO:8]
71 const PPC64Instr kDecoderMask9 = (0x3F << 26) | (0xFF << 3);
72 // VA-FORM or A-FORM [OP:6 [XO:8 |XO:8 Rc:1]]
73 const PPC64Instr kDecoderMask10 = (0x3F << 26) | (0x3F);
74 // M-FORM [OP:6 ME:5 Rc:1]
75 const PPC64Instr kDecoderMask11 = (0x3F << 26) | (0x1F << 2) | (0x1);
76 // MDS-FORM [OP:6 XO:5 Rc:1 ]
77 const PPC64Instr kDecoderMask12 = (0x3F << 26) | (0x1F << 1);
78 // XX3-FORM [OP:6 XO1:1 XO2:4]
79 const PPC64Instr kDecoderMask13 = (0x3F << 26) | (0xF << 3) | (0x1 << 10);
80 // MDS FORM [OP:6 XO:4 Rc:1]
81 const PPC64Instr kDecoderMask14 = (0x3F << 26) | (0xF << 1) | (0x1);
82 // MD FORM [OP:6 XO:2 Rc:1]
83 const PPC64Instr kDecoderMask15 = (0x3F << 26) | (0x7 << 2) | (0x1);
84 // XX4-FORM [OP:6 XO:2]
85 const PPC64Instr kDecoderMask16 = (0x3F << 26) | (0x3 << 4);
86 // I-FORM or B-FORM or DS-FORM [OP:6 [AA:1 LK:1 | XO:2]]
87 const PPC64Instr kDecoderMask17 = (0x3F << 26) | (0x3);
88 // TODO(rcardoso): maybe useless
89 // (?????) [OP:6 XO:2]
90 const PPC64Instr kDecoderMask18 = (0x3F << 26) | (0x1 << 2) | (0x1 << 1);
91 // SC-FORM [OP:6 0x1:1]
92 const PPC64Instr kDecoderMask19 = (0x3F << 26) | (0x1 << 1);
93 // M-FORM [OP:6 Rc:1]
94 const PPC64Instr kDecoderMask20 = (0x3F << 26) | (0x1);
95 // DQ-FORM or D-FORM [OP:6]
96 const PPC64Instr kDecoderMask21 = (0x3F << 26);
98 // Decoder List
99 const PPC64Instr DecoderList[] = {
100 kDecoderMask1, kDecoderMask2, kDecoderMask3, kDecoderMask4,
101 kDecoderMask5, kDecoderMask6, kDecoderMask7, kDecoderMask8,
102 kDecoderMask9, kDecoderMask10, kDecoderMask11, kDecoderMask12,
103 kDecoderMask13, kDecoderMask14, kDecoderMask15, kDecoderMask16,
104 kDecoderMask17, kDecoderMask18, kDecoderMask19, kDecoderMask20,
105 kDecoderMask21
109 * Defines operands mask and type for a instruction. The flags can be
110 * used to encode information about a operand like kind of register or
111 * if a immediate will be print as a signed or unsigned value.
113 struct Operands {
114 PPC64Instr m_mask;
115 PPC64Instr m_flags;
117 Operands(PPC64Instr mask, PPC64Instr flags)
118 : m_mask(mask)
119 , m_flags(flags)
121 Operands()
122 : m_mask(0)
123 , m_flags(0)
126 // calculates operand mask shift factor
127 int operandShift() {
128 int s = 32;
129 if (m_mask) {
130 PPC64Instr n = m_mask;
131 n = (n ^ (n - 1)) >> 1;
132 for (s = 0; n; s++) {
133 n >>=1;
136 return s;
140 // Instructions information.
141 // First element is the fallback to invalid opcodes and they are sorted based
142 // on its opcode.
144 // All the DecoderInfo identifiers are macros defined in decoder-ppc64.cpp.
145 #define PPC64_OPCODES \
146 DE(invalid, 0x0, Form::kInvalid, invalid, { UN }) \
147 DE(cmpli, 0x28000000, Form::kD, cmpli, { BF, L, RA, UI }) \
148 DE(cmpi, 0x2C000000, Form::kD, cmpi, { BF, L, RA, SI }) \
149 DE(addicdot, 0x34000000, Form::kD, addic., { RT, RA, SI }) \
150 DE(addi, 0x38000000, Form::kD, addi, { RT, RA0, SI }) \
151 DE(addis, 0x3C000000, Form::kD, addis, { RT, RA0, SISIGNOPT }) \
152 DE(bc, 0x40000000, Form::kB, bc, { BO, BI, BD }) \
153 DE(bcl, 0x40000001, Form::kB, bcl, { BO, BI, BD }) \
154 DE(bca, 0x40000002, Form::kB, bca, { BO, BI, BDA }) \
155 DE(bcla, 0x40000003, Form::kB, bcla, { BO, BI, BDA }) \
156 DE(b, 0x48000000, Form::kI, b, { LI }) \
157 DE(bl, 0x48000001, Form::kI, bl, { LI }) \
158 DE(ba, 0x48000002, Form::kI, ba, { LIA }) \
159 DE(bla, 0x48000003, Form::kI, bla, { LIA }) \
160 DE(bclr, 0x4C000020, Form::kXL, bclr, { BO, BI, BH }) \
161 DE(bclrl, 0x4C000021, Form::kXL, bclrl, { BO, BI, BH }) \
162 DE(bcctr, 0x4C000420, Form::kXL, bcctr, { BO, BI, BH }) \
163 DE(bcctrl, 0x4C000421, Form::kXL, bcctrl, { BO, BI, BH }) \
164 DE(bctar, 0x4C000460, Form::kX, bctar, { BO, BI, BH }) \
165 DE(bctarl, 0x4C000461, Form::kX, bctarl, { BO, BI, BH }) \
166 DE(rlwimidot, 0x50000001, Form::kM, rlwimi., { RA,RS,SH,MBE,ME }) \
167 DE(rlwinm, 0x54000000, Form::kM, rlwinm, { RA,RS,SH,MBE,ME }) \
168 DE(rlwinmdot, 0x54000001, Form::kM, rlwinm., { RA,RS,SH,MBE,ME }) \
169 DE(rlwnmdot, 0x5C000001, Form::kM, rlwnm., { RA,RS,RB,MBE,ME }) \
170 DE(ori, 0x60000000, Form::kD, ori, { RA, RS, UI }) \
171 DE(oris, 0x64000000, Form::kD, oris, { RA, RS, UI }) \
172 DE(andidot, 0x70000000, Form::kD, andi., { RA, RS, UI }) \
173 DE(andisdot, 0x74000000, Form::kD, andis., { RA, RS, UI }) \
174 DE(rldicl, 0x78000000, Form::kMD, rldicl, { RA, RS, SH6, MB6 }) \
175 DE(rldicldot, 0x78000001, Form::kMD, rldicl., { RA, RS, SH6, MB6 }) \
176 DE(rldicr, 0x78000004, Form::kMD, rldicr, { RA, RS, SH6, ME6 }) \
177 DE(rldicrdot, 0x78000005, Form::kMD, rldicr., { RA, RS, SH6, ME6 }) \
178 DE(rldicdot, 0x78000009, Form::kMD, rldic., { RA, RS, SH6, MB6 }) \
179 DE(rldimidot, 0x7800000D, Form::kMD, rldimi., { RA, RS, SH6, MB6 }) \
180 DE(rldcldot, 0x78000011, Form::kMDS, rldcl., { RA, RS, RB, MB6 }) \
181 DE(rldcrdot, 0x78000013, Form::kMDS, rldcr., { RA, RS, RB, ME6 }) \
182 DE(cmp, 0x7C000000, Form::kX, cmp, { BF, L, RA, RB }) \
183 DE(tw, 0x7C000008, Form::kX, tw, { TO, RA, RB }) \
184 DE(subfcdot, 0x7C000011, Form::kXO, subfc., { RT, RA, RB }) \
185 DE(mulhdudot, 0x7C000013, Form::kXO, mulhdu., { RT, RA, RB }) \
186 DE(addcdot, 0x7C000015, Form::kXO, addc., { RT, RA, RB }) \
187 DE(mulhwudot, 0x7C000017, Form::kXO, mulhwu., { RT, RA, RB }) \
188 DE(isel, 0x7C00001E, Form::kA, isel, { RT, RA, RB, CRB }) \
189 DE(mfcr, 0x7C000026, Form::kXFX, mfcr, { RT }) \
190 DE(ldx, 0x7C00002A, Form::kX, ldx, { RT, RA0, RB }) \
191 DE(lwzx, 0x7C00002E, Form::kX, lwzx, { RT, RA0, RB }) \
192 DE(slwdot, 0x7C000031, Form::kX, slw., { RA, RS, RB }) \
193 DE(cntlzwdot, 0x7C000035, Form::kX, cntlzw., { RA, RS }) \
194 DE(sld, 0x7C000036, Form::kX, sld, { RA, RS, RB }) \
195 DE(slddot, 0x7C000037, Form::kX, sld., { RA, RS, RB }) \
196 DE(and, 0x7C000038, Form::kX, and, { RA, RS, RB }) \
197 DE(anddot, 0x7C000039, Form::kX, and., { RA, RS, RB }) \
198 DE(cmpl, 0x7C000040, Form::kX, cmpl, { BF, L, RA, RB }) \
199 DE(subf, 0x7C000050, Form::kXO, subf, { RT, RA, RB }) \
200 DE(subfdot, 0x7C000051, Form::kXO, subf., { RT, RA, RB }) \
201 DE(mfvsrd, 0x7C000066, Form::kXX1, mfvsrd, { RA, XS }) \
202 DE(cntlzddot, 0x7C000075, Form::kX, cntlzd., { RA, RS }) \
203 DE(andcdot, 0x7C000079, Form::kX, andc., { RA, RS, RB }) \
204 DE(td, 0x7C000088, Form::kX, td, { TO, RA, RB }) \
205 DE(mulhddot, 0x7C000093, Form::kXO, mulhd., { RT, RA, RB }) \
206 DE(mulhwdot, 0x7C000097, Form::kXO, mulhw., { RT, RA, RB }) \
207 DE(mfmsr, 0x7C0000A6, Form::kX, mfmsr, { RT }) \
208 DE(ldarx, 0x7C0000A8, Form::kX, ldarx, { RT, RA0, RB, EH }) \
209 DE(lbzx, 0x7C0000AE, Form::kX, lbzx, { RT, RA0, RB }) \
210 DE(neg, 0x7C0000D0, Form::kXO, neg, { RT, RA }) \
211 DE(negdot, 0x7C0000D1, Form::kXO, neg., { RT, RA }) \
212 DE(nor, 0x7C0000F8, Form::kX, nor, { RA, RS, RB }) \
213 DE(nordot, 0x7C0000F9, Form::kX, nor., { RA, RS, RB }) \
214 DE(subfedot, 0x7C000111, Form::kXO, subfe., { RT, RA, RB }) \
215 DE(addedot, 0x7C000115, Form::kXO, adde., { RT, RA, RB }) \
216 DE(mtcrf, 0x7C000120, Form::kXFX, mtcrf, { FXM, RS }) \
217 DE(mtmsr, 0x7C000124, Form::kX, mtmsr, { RS }) \
218 DE(stdx, 0x7C00012A, Form::kX, stdx, { RS, RA0, RB }) \
219 DE(stwx, 0x7C00012E, Form::kX, stwx, { RS, RA0, RB }) \
220 DE(mtmsrd, 0x7C000164, Form::kX, mtmsrd, { RS, A_L }) \
221 DE(mtvsrd, 0x7C000166, Form::kXX1, mtvsrd, { XT, RA }) \
222 DE(subfzedot, 0x7C000191, Form::kXO, subfze., { RT, RA }) \
223 DE(addzedot, 0x7C000195, Form::kXO, addze., { RT, RA }) \
224 DE(stdcxdot, 0x7C0001AD, Form::kX, stdcx., { RS, RA0, RB }) \
225 DE(stbx, 0x7C0001AE, Form::kX, stbx, { RS, RA0, RB }) \
226 DE(subfmedot, 0x7C0001D1, Form::kXO, subfme., { RT, RA }) \
227 DE(mullddot, 0x7C0001D3, Form::kXO, mulld., { RT, RA, RB }) \
228 DE(addmedot, 0x7C0001D5, Form::kXO, addme., { RT, RA }) \
229 DE(mullwdot, 0x7C0001D7, Form::kXO, mullw., { RT, RA, RB }) \
230 DE(add, 0x7C000214, Form::kXO, add, { RT, RA, RB }) \
231 DE(adddot, 0x7C000215, Form::kXO, add., { RT, RA, RB }) \
232 DE(lhzx, 0x7C00022E, Form::kX, lhzx, { RT, RA0, RB }) \
233 DE(eqvdot, 0x7C000239, Form::kX, eqv., { RA, RS, RB }) \
234 DE(xor, 0x7C000278, Form::kX, xor, { RA, RS, RB }) \
235 DE(xordot, 0x7C000279, Form::kX, xor., { RA, RS, RB }) \
236 DE(mfspr, 0x7C0002A6, Form::kXFX, mfspr, { RT, SPR }) \
237 DE(mftb, 0x7C0002E6, Form::kXFX, mftb, { RT, TBR }) \
238 DE(divdeudot, 0x7C000313, Form::kXO, divdeu., { RT, RA, RB }) \
239 DE(divweudot, 0x7C000317, Form::kXO, divweu., { RT, RA, RB }) \
240 DE(sthx, 0x7C00032E, Form::kX, sthx, { RS, RA0, RB }) \
241 DE(orcdot, 0x7C000339, Form::kX, orc., { RA, RS, RB }) \
242 DE(divdedot, 0x7C000353, Form::kXO, divde., { RT, RA, RB }) \
243 DE(divwedot, 0x7C000357, Form::kXO, divwe., { RT, RA, RB }) \
244 DE(or, 0x7C000378, Form::kX, or, { RA, RS, RB }) \
245 DE(ordot, 0x7C000379, Form::kX, or., { RA, RS, RB }) \
246 DE(divdudot, 0x7C000393, Form::kXO, divdu., { RT, RA, RB }) \
247 DE(divwudot, 0x7C000397, Form::kXO, divwu., { RT, RA, RB }) \
248 DE(mtpmr, 0x7C00039C, Form::kXFX, mtpmr, { PMR, RS }) \
249 DE(mtspr, 0x7C0003A6, Form::kXFX, mtspr, { SPR, RS }) \
250 DE(nanddot, 0x7C0003B9, Form::kX, nand., { RA, RS, RB }) \
251 DE(dcread2, 0x7C0003CC, Form::kX, dcread, { RT, RA, RB }) \
252 DE(divd, 0x7C0003D2, Form::kXO, divd, { RT, RA, RB }) \
253 DE(divddot, 0x7C0003D3, Form::kXO, divd., { RT, RA, RB }) \
254 DE(divwdot, 0x7C0003D7, Form::kXO, divw., { RT, RA, RB }) \
255 DE(cmpb, 0x7C0003F8, Form::kX, cmpb, { RA, RS, RB }) \
256 DE(subfcodot, 0x7C000411, Form::kXO, subfco., { RT, RA, RB }) \
257 DE(addcodot, 0x7C000415, Form::kXO, addco., { RT, RA, RB }) \
258 DE(srwdot, 0x7C000431, Form::kX, srw., { RA, RS, RB }) \
259 DE(srddot, 0x7C000437, Form::kX, srd., { RA, RS, RB }) \
260 DE(subfo, 0x7C000450, Form::kXO, subfo, { RT, RA, RB }) \
261 DE(subfodot, 0x7C000451, Form::kXO, subfo., { RT, RA, RB }) \
262 DE(lfdx, 0x7C0004AE, Form::kX, lfdx, { FRT, RA0, RB }) \
263 DE(negodot, 0x7C0004D1, Form::kXO, nego., { RT, RA }) \
264 DE(subfeodot, 0x7C000511, Form::kXO, subfeo., { RT, RA, RB }) \
265 DE(addeodot, 0x7C000515, Form::kXO, addeo., { RT, RA, RB }) \
266 DE(subfzeodot, 0x7C000591, Form::kXO, subfzeo., { RT, RA }) \
267 DE(addzeodot, 0x7C000595, Form::kXO, addzeo., { RT, RA }) \
268 DE(stfdx, 0x7C0005AE, Form::kX, stfdx, { FRS, RA0, RB }) \
269 DE(subfmeodot, 0x7C0005D1, Form::kXO, subfmeo., { RT, RA }) \
270 DE(mulldo, 0x7C0005D2, Form::kXO, mulldo, { RT, RA, RB }) \
271 DE(mulldodot, 0x7C0005D3, Form::kXO, mulldo., { RT, RA, RB }) \
272 DE(addmeodot, 0x7C0005D5, Form::kXO, addmeo., { RT, RA }) \
273 DE(mullwodot, 0x7C0005D7, Form::kXO, mullwo., { RT, RA, RB }) \
274 DE(addo, 0x7C000614, Form::kXO, addo, { RT, RA, RB }) \
275 DE(addodot, 0x7C000615, Form::kXO, addo., { RT, RA, RB }) \
276 DE(lxvw4x, 0x7C000618, Form::kXX1, lxvw4x, { XT, RA, RB }) \
277 DE(srawdot, 0x7C000631, Form::kX, sraw., { RA, RS, RB }) \
278 DE(srad, 0x7C000634, Form::kX, srad, { RA, RS, RB }) \
279 DE(sraddot, 0x7C000635, Form::kX, srad., { RA, RS, RB }) \
280 DE(srawidot, 0x7C000671, Form::kX, srawi., { RA, RS, SH }) \
281 DE(sradi, 0x7C000674, Form::kXS, sradi, { RA, RS, SH6 }) \
282 DE(sradidot, 0x7C000675, Form::kXS, sradi., { RA, RS, SH6 }) \
283 DE(lxvd2x, 0x7C000698, Form::kXX1, lxvd2x, { XT, RA, RB }) \
284 DE(divdeuodot, 0x7C000713, Form::kXO, divdeuo., { RT, RA, RB }) \
285 DE(divweuodot, 0x7C000717, Form::kXO, divweuo., { RT, RA, RB }) \
286 DE(stxvw4x, 0x7C000718, Form::kXX1, stxvw4x, { XS, RA, RB }) \
287 DE(extsh, 0x7C000734, Form::kX, extsh, { RA, RS }) \
288 DE(extshdot, 0x7C000735, Form::kX, extsh., { RA, RS }) \
289 DE(divdeodot, 0x7C000753, Form::kXO, divdeo., { RT, RA, RB }) \
290 DE(divweodot, 0x7C000757, Form::kXO, divweo., { RT, RA, RB }) \
291 DE(extsb, 0x7C000774, Form::kX, extsb, { RA, RS}) \
292 DE(extsbdot, 0x7C000775, Form::kX, extsb., { RA, RS}) \
293 DE(divduodot, 0x7C000793, Form::kXO, divduo., { RT, RA, RB }) \
294 DE(divwuodot, 0x7C000797, Form::kXO, divwuo., { RT, RA, RB }) \
295 DE(extsw, 0x7C0007B4, Form::kX, extsw, { RA, RS }) \
296 DE(extswdot, 0x7C0007B5, Form::kX, extsw., { RA, RS }) \
297 DE(divdodot, 0x7C0007D3, Form::kXO, divdo., { RT, RA, RB }) \
298 DE(divwodot, 0x7C0007D7, Form::kXO, divwo., { RT, RA, RB }) \
299 DE(mtocrf, 0x7C100120, Form::kXFX, mtocrf, { FXM, RS }) \
300 DE(lwz, 0x80000000, Form::kD, lwz, { RT, D, RA0 }) \
301 DE(lbz, 0x88000000, Form::kD, lbz, { RT, D, RA0 }) \
302 DE(stw, 0x90000000, Form::kD, stw, { RS, D, RA0 }) \
303 DE(stb, 0x98000000, Form::kD, stb, { RS, D, RA0 }) \
304 DE(lhz, 0xA0000000, Form::kD, lhz, { RT, D, RA0 }) \
305 DE(sth, 0xB0000000, Form::kD, sth, { RS, D, RA0 }) \
306 DE(lfs, 0xC0000000, Form::kD, lfs, { FRT, D, RA0 }) \
307 DE(lfd, 0xC8000000, Form::kD, lfd, { FRT, D, RA0 }) \
308 DE(stfs, 0xD0000000, Form::kD, stfs, { FRS, D, RA0 }) \
309 DE(stfd, 0xD8000000, Form::kD, stfd, { FRS, D, RA0 }) \
310 DE(ld, 0xE8000000, Form::kDS, ld, { RT, DS, RA0 }) \
311 DE(frsqrtes, 0xEC000034, Form::kA, frsqrtes, { FRT, FRB, A_L }) \
312 DE(frsqrtesdot, 0xEC000035, Form::kA, frsqrtes., { FRT, FRB, A_L }) \
313 DE(dcmpu, 0xEC000504, Form::kX, dcmpu, { BF, FRA, FRB }) \
314 DE(fcfids, 0xEC00069C, Form::kX, fcfids, { FRT, FRB }) \
315 DE(fcfidsdot, 0xEC00069D, Form::kX, fcfids., { FRT, FRB }) \
316 DE(xxpermdi, 0xF0000050, Form::kXX3, xxpermdi, { XT, XA, XB, DM }) \
317 DE(xsrdpi, 0xF0000124, Form::kXX2, xsrdpi, { XT, XB }) \
318 DE(xssqrtdp, 0xF000012C, Form::kXX2, xssqrtdp, { XT, XB }) \
319 DE(xvcvspsxws, 0xF0000260, Form::kXX2, xvcvspsxws, { XT, XB }) \
320 DE(xvdivsp, 0xF00002C0, Form::kXX3, xvdivsp, { XT, XA, XB }) \
321 DE(xvdivdp, 0xF00003C0, Form::kXX3, xvdivdp, { XT, XA, XB }) \
322 DE(xxlxor, 0xF00004D0, Form::kXX3, xxlxor, { XT, XA, XB }) \
323 DE(xscvdpuxds, 0xF0000520, Form::kXX2, xscvdpuxds, { XT, XB }) \
324 DE(xscvdpsxds, 0xF0000560, Form::kXX2, xscvdpsxds, { XT, XB }) \
325 DE(xscvsxddp, 0xF00005E0, Form::kXX2, xscvsxddp, { XT, XB }) \
326 DE(xvcvspsxds, 0xF0000660, Form::kXX2, xvcvspsxds, { XT, XB }) \
327 DE(std, 0xF8000000, Form::kDS, std, { RS, DS, RA0 }) \
328 DE(stdu, 0xF8000001, Form::kDS, stdu, { RS, DS, RAS }) \
329 DE(fcmpu, 0xFC000000, Form::kX, fcmpu, { BF, FRA, FRB }) \
330 DE(fadd, 0xFC00002A, Form::kA, fadd, { FRT, FRA, FRB }) \
331 DE(fadddot, 0xFC00002B, Form::kA, fadd., { FRT, FRA, FRB }) \
332 DE(fcmpo, 0xFC000040, Form::kX, fcmpo, { BF, FRA, FRB }) \
333 DE(mcrfs, 0xFC000080, Form::kX, mcrfs, { BF, BFA }) \
334 DE(mtfsb0, 0xFC00008C, Form::kX, mtfsb0, { BT }) \
335 DE(mtfsb0dot, 0xFC00008D, Form::kX, mtfsb0., { BT }) \
336 DE(fmr, 0xFC000090, Form::kX, fmr, { FRT, FRB }) \
337 DE(fmrdot, 0xFC000091, Form::kX, fmr., { FRT, FRB }) \
338 DE(fabs, 0xFC000210, Form::kX, fabs, { FRT, FRB }) \
339 DE(fabsdot, 0xFC000211, Form::kX, fabs., { FRT, FRB }) \
340 DE(fctid, 0xFC00065C, Form::kX, fctid, { FRT, FRB }) \
341 DE(fctiddot, 0xFC00065D, Form::kX, fctid., { FRT, FRB }) \
342 DE(fctidz, 0xFC00065E, Form::kX, fctidz, { FRT, FRB }) \
343 DE(fctidzdot, 0xFC00065F, Form::kX, fctidz., { FRT, FRB }) \
344 DE(fcfid, 0xFC00069C, Form::kX, fcfid, { FRT, FRB }) \
345 DE(fcfiddot, 0xFC00069D, Form::kX, fcfid., { FRT, FRB }) \
346 /* */
348 enum class OpcodeNames {
349 #define DE(name, op, type, mnemonic, ... ) \
350 op_##name,
352 PPC64_OPCODES
354 #undef DE
356 op_last
359 // appropriate cast for array manipulation
360 constexpr size_t kTotalOpcodes = static_cast<size_t>(OpcodeNames::op_last);
362 enum class AllowCond {
363 OnlyUncond,
364 Any,
365 OnlyCond
368 struct DecoderInfo {
369 DecoderInfo(OpcodeNames opn, PPC64Instr op, Form form,
370 std::string mnemonic, std::initializer_list<Operands> oper)
371 : m_opn(opn)
372 , m_ip(nullptr)
373 , m_op(op)
374 , m_form(form)
375 , m_mnemonic(mnemonic)
376 , m_image(0x0) {
377 // pushing it in reverse order
378 for (auto it = oper.begin(); it != oper.end(); it++) {
379 m_operands.push_back(*it);
383 ~DecoderInfo() {}
385 DecoderInfo() = delete;
387 inline const uint8_t* ip() const { return m_ip; }
388 inline Form form() const { return m_form; }
389 inline OpcodeNames opcode_name() const { return m_opn; }
390 inline PPC64Instr opcode() const { return m_op; }
391 inline std::string mnemonic() const { return m_mnemonic; }
392 std::string toString() const;
394 const PPC64Instr instruction_image() const { return m_image; }
395 void instruction_image(const PPC64Instr i) { m_image = i; }
397 inline bool operator==(const DecoderInfo& i) {
398 return (i.form() == m_form &&
399 i.opcode() == m_op &&
400 i.mnemonic() == m_mnemonic);
403 inline bool operator!=(const DecoderInfo& i) {
404 return (i.form() != m_form ||
405 i.opcode() != m_op ||
406 i.mnemonic() != m_mnemonic);
409 bool isInvalid() const {
410 return m_opn == OpcodeNames::op_invalid;
412 bool isException() const;
413 bool isNop() const;
414 bool isOffsetBranch(AllowCond ac = AllowCond::Any) const;
415 bool isRegisterBranch(AllowCond ac = AllowCond::Any) const;
416 bool isBranchWithLR() const;
417 bool isClearSignBit() const;
418 bool isSpOffsetInstr() const;
419 int32_t offset() const;
420 int32_t branchOffset() const;
421 PPC64Instr setBranchOffset(int32_t offset) const;
422 void setIp(const uint8_t* const ip) { m_ip = ip; }
423 void setIp(const PPC64Instr* const ip) {
424 setIp(reinterpret_cast<const uint8_t* const>(ip));
426 bool isAddis(bool toc = false) const;
427 bool isLd(bool toc = false) const;
428 bool isLwz(bool toc = false) const;
429 int16_t offsetDS() const;
430 int16_t offsetD() const;
432 private:
433 // Auxiliary function for isLd and isLwz
434 bool isDformOp(OpcodeNames opn, bool toc) const;
436 // opcode enumeration identifier
437 OpcodeNames m_opn;
438 // pointer to the decoded instruction in the memory
439 const uint8_t* m_ip;
440 // the opcode part of the instruction
441 PPC64Instr m_op;
442 // points out which -Form the instruction is
443 Form m_form;
444 // the mnemonic string of the instruction
445 std::string m_mnemonic;
446 // the complete instruction, as used to decode
447 PPC64Instr m_image;
448 // operands list
449 std::deque<Operands> m_operands;
452 class Decoder : private boost::noncopyable {
453 DecoderInfo **m_decoder_table;
454 DecoderInfo **m_opcode_index_table;
455 static Decoder* s_decoder;
456 std::map<int32_t, int32_t> opcode_index_map;
457 std::map<int32_t, int32_t> opcode_size_map;
458 int32_t m_decoder_table_size;
460 void setInstruction(DecoderInfo dinfo) {
462 m_decoder_table[m_decoder_table_size++] = new DecoderInfo(dinfo);
464 m_opcode_index_table[static_cast<PPC64Instr>(dinfo.opcode_name())] =
465 m_decoder_table[m_decoder_table_size];
469 * Create index based on opcode to help when searching the instruction.
471 void createOpcodeIndex () {
472 PPC64Instr current_opcode = 0x0;
473 int32_t current_index = 0;
475 opcode_index_map[current_opcode] = current_index;
476 for (int i = 0; i < m_decoder_table_size; i++) {
477 PPC64Instr tmp_opcode = m_decoder_table[i]->opcode() & kOpcodeMask;
478 if (current_opcode != tmp_opcode) {
479 opcode_size_map[current_opcode] = i - current_index; // set size
480 current_opcode = tmp_opcode;
481 current_index = i;
482 opcode_index_map[current_opcode] = current_index;
487 Decoder();
489 ~Decoder() {
490 for(int i = 0; i < kDecoderSize; i++)
491 if(m_decoder_table[i] != nullptr) {
492 delete m_decoder_table[i];
494 delete[] m_decoder_table;
497 public:
498 const DecoderInfo getInvalid() {
499 return *m_decoder_table[static_cast<size_t>(OpcodeNames::op_invalid)];
502 static Decoder& GetDecoder() {
503 static Decoder dec;
504 s_decoder = &dec;
505 return *s_decoder;
508 const DecoderInfo decode(const PPC64Instr* const ip);
510 int32_t searchInstr(
511 int32_t opc_index,
512 int32_t opc_size,
513 PPC64Instr instr) const;
515 inline const DecoderInfo decode(const uint8_t* const ip) {
516 return decode(reinterpret_cast<const PPC64Instr* const>(ip));
520 } // namespace ppc64_asm
522 #endif