1 /*
2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 
26 package jdk.tools.jaotc.amd64;
27 
28 import jdk.tools.jaotc.InstructionDecoder;
29 
30 import jdk.vm.ci.code.TargetDescription;
31 
32 public final class AMD64InstructionDecoder extends InstructionDecoder {
33 
34     private boolean targetIs64Bit;
35     private int currentEndOfInstruction;
36 
37     private static class Prefix {
38 
39         // segment overrides
40         static final int CSSegment = 0x2e;
41         static final int SSSegment = 0x36;
42         static final int DSSegment = 0x3e;
43         static final int ESSegment = 0x26;
44         static final int FSSegment = 0x64;
45         static final int GSSegment = 0x65;
46         static final int REX = 0x40;
47         static final int REXB = 0x41;
48         static final int REXX = 0x42;
49         static final int REXXB = 0x43;
50         static final int REXR = 0x44;
51         static final int REXRB = 0x45;
52         static final int REXRX = 0x46;
53         static final int REXRXB = 0x47;
54         static final int REXW = 0x48;
55         static final int REXWB = 0x49;
56         static final int REXWX = 0x4A;
57         static final int REXWXB = 0x4B;
58         static final int REXWR = 0x4C;
59         static final int REXWRB = 0x4D;
60         static final int REXWRX = 0x4E;
61         static final int REXWRXB = 0x4F;
62         static final int VEX_3BYTES = 0xC4;
63         static final int VEX_2BYTES = 0xC5;
64     }
65 
66     @SuppressWarnings("unused")
67     private static class VexPrefix {
68         static final int VEX_R = 0x80;
69         static final int VEX_W = 0x80;
70     }
71 
72     @SuppressWarnings("unused")
73     private static class VexOpcode {
74         static final int VEX_OPCODE_NONE = 0x0;
75         static final int VEX_OPCODE_0F = 0x1;
76         static final int VEX_OPCODE_0F_38 = 0x2;
77         static final int VEX_OPCODE_0F_3A = 0x3;
78         static final int VEX_OPCODE_MASK = 0x1F;
79     }
80 
AMD64InstructionDecoder(TargetDescription target)81     public AMD64InstructionDecoder(TargetDescription target) {
82         this.targetIs64Bit = target.wordSize == 8;
83     }
84 
85     @Override
currentEndOfInstruction()86     public int currentEndOfInstruction() {
87         return currentEndOfInstruction;
88     }
89 
90     @Override
91     @SuppressWarnings("fallthrough")
decodePosition(final byte[] code, int pcOffset)92     public void decodePosition(final byte[] code, int pcOffset) {
93         assert pcOffset >= 0 && pcOffset < code.length;
94 
95         // Decode the given instruction, and return the Pointer of
96         // an embedded 32-bit operand word.
97 
98         // If "which" is WhichOperand.disp32operand, selects the displacement portion
99         // of an effective Pointer specifier.
100         // If "which" is imm64Operand, selects the trailing immediate constant.
101         // If "which" is WhichOperand.call32operand, selects the displacement of a call or jump.
102         // Caller is responsible for ensuring that there is such an operand,
103         // and that it is 32/64 bits wide.
104 
105         // If "which" is endPcOperand, find the end of the instruction.
106 
107         int ip = pcOffset;
108         boolean is64bit = false;
109 
110         boolean hasDisp32 = false;
111         int tailSize = 0; // other random bytes (#32, #16, etc.) at end of insn
112 
113         boolean againAfterPrefix = true;
114 
115         while (againAfterPrefix) {
116             againAfterPrefix = false;
117             switch (0xFF & code[ip++]) {
118 
119                 // These convenience macros generate groups of "case" labels for the switch.
120 
121                 case Prefix.CSSegment:
122                 case Prefix.SSSegment:
123                 case Prefix.DSSegment:
124                 case Prefix.ESSegment:
125                 case Prefix.FSSegment:
126                 case Prefix.GSSegment:
127                     // Seems dubious
128                     assert !targetIs64Bit : "shouldn't have that prefix";
129                     assert ip == pcOffset + 1 : "only one prefix allowed";
130                     againAfterPrefix = true;
131                     break;
132 
133                 case 0x67:
134                 case Prefix.REX:
135                 case Prefix.REXB:
136                 case Prefix.REXX:
137                 case Prefix.REXXB:
138                 case Prefix.REXR:
139                 case Prefix.REXRB:
140                 case Prefix.REXRX:
141                 case Prefix.REXRXB:
142                     assert targetIs64Bit : "64bit prefixes";
143                     againAfterPrefix = true;
144                     break;
145 
146                 case Prefix.REXW:
147                 case Prefix.REXWB:
148                 case Prefix.REXWX:
149                 case Prefix.REXWXB:
150                 case Prefix.REXWR:
151                 case Prefix.REXWRB:
152                 case Prefix.REXWRX:
153                 case Prefix.REXWRXB:
154                     assert targetIs64Bit : "64bit prefixes";
155                     is64bit = true;
156                     againAfterPrefix = true;
157                     break;
158 
159                 case 0xFF: // pushq a; decl a; incl a; call a; jmp a
160                 case 0x88: // movb a, r
161                 case 0x89: // movl a, r
162                 case 0x8A: // movb r, a
163                 case 0x8B: // movl r, a
164                 case 0x8F: // popl a
165                     hasDisp32 = true;
166                     break;
167 
168                 case 0x68: // pushq #32
169                     currentEndOfInstruction = ip + 4;
170                     return; // not produced by emitOperand
171 
172                 case 0x66: // movw ... (size prefix)
173                     boolean againAfterSizePrefix2 = true;
174                     while (againAfterSizePrefix2) {
175                         againAfterSizePrefix2 = false;
176                         switch (0xFF & code[ip++]) {
177                             case Prefix.REX:
178                             case Prefix.REXB:
179                             case Prefix.REXX:
180                             case Prefix.REXXB:
181                             case Prefix.REXR:
182                             case Prefix.REXRB:
183                             case Prefix.REXRX:
184                             case Prefix.REXRXB:
185                             case Prefix.REXW:
186                             case Prefix.REXWB:
187                             case Prefix.REXWX:
188                             case Prefix.REXWXB:
189                             case Prefix.REXWR:
190                             case Prefix.REXWRB:
191                             case Prefix.REXWRX:
192                             case Prefix.REXWRXB:
193                                 assert targetIs64Bit : "64bit prefix found";
194                                 againAfterSizePrefix2 = true;
195                                 break;
196                             case 0x8B: // movw r, a
197                             case 0x89: // movw a, r
198                                 hasDisp32 = true;
199                                 break;
200                             case 0xC7: // movw a, #16
201                                 hasDisp32 = true;
202                                 tailSize = 2; // the imm16
203                                 break;
204                             case 0x0F: // several SSE/SSE2 variants
205                                 ip--; // reparse the 0x0F
206                                 againAfterPrefix = true;
207                                 break;
208                             default:
209                                 throw new InternalError("should not reach here");
210                         }
211                     }
212                     break;
213 
214                 case 0xB8: // movl/q r, #32/#64(oop?)
215                 case 0xB9:
216                 case 0xBA:
217                 case 0xBB:
218                 case 0xBC:
219                 case 0xBD:
220                 case 0xBE:
221                 case 0xBF:
222                     currentEndOfInstruction = ip + (is64bit ? 8 : 4);
223                     return;
224 
225                 case 0x69: // imul r, a, #32
226                 case 0xC7: // movl a, #32(oop?)
227                     tailSize = 4;
228                     hasDisp32 = true; // has both kinds of operands!
229                     break;
230 
231                 case 0x0F: // movx..., etc.
232                     switch (0xFF & code[ip++]) {
233                         case 0x3A: // pcmpestri
234                             ip++; // skip opcode
235                             tailSize = 1;
236                             hasDisp32 = true; // has both kinds of operands!
237                             break;
238 
239                         case 0x38: // ptest, pmovzxbw
240                             ip++; // skip opcode
241                             hasDisp32 = true; // has both kinds of operands!
242                             break;
243 
244                         case 0x70: // pshufd r, r/a, #8
245                             hasDisp32 = true; // has both kinds of operands!
246                             tailSize = 1;
247                             break;
248 
249                         case 0x73: // psrldq r, #8
250                             tailSize = 1;
251                             break;
252 
253                         case 0x12: // movlps
254                         case 0x28: // movaps
255                         case 0x2E: // ucomiss
256                         case 0x2F: // comiss
257                         case 0x54: // andps
258                         case 0x55: // andnps
259                         case 0x56: // orps
260                         case 0x57: // xorps
261                         case 0x58: // addpd
262                         case 0x59: // mulpd
263                         case 0x6E: // movd
264                         case 0x7E: // movd
265                         case 0xAE: // ldmxcsr, stmxcsr, fxrstor, fxsave, clflush
266                         case 0xFE: // paddd
267                             // 64bit side says it these have both operands but that doesn't
268                             // appear to be true
269                             hasDisp32 = true;
270                             break;
271 
272                         case 0xAD: // shrd r, a, %cl
273                         case 0xAF: // imul r, a
274                         case 0xBE: // movsbl r, a (movsxb)
275                         case 0xBF: // movswl r, a (movsxw)
276                         case 0xB6: // movzbl r, a (movzxb)
277                         case 0xB7: // movzwl r, a (movzxw)
278                         case 0x40: // cmovl cc, r, a
279                         case 0x41:
280                         case 0x42:
281                         case 0x43:
282                         case 0x44:
283                         case 0x45:
284                         case 0x46:
285                         case 0x47:
286                         case 0x48:
287                         case 0x49:
288                         case 0x4A:
289                         case 0x4B:
290                         case 0x4C:
291                         case 0x4D:
292                         case 0x4E:
293                         case 0x4F:
294                         case 0xB0: // cmpxchgb
295                         case 0xB1: // cmpxchg
296                         case 0xC1: // xaddl
297                         case 0xC7: // cmpxchg8
298                         case 0x90: // setcc a
299                         case 0x91:
300                         case 0x92:
301                         case 0x93:
302                         case 0x94:
303                         case 0x95:
304                         case 0x96:
305                         case 0x97:
306                         case 0x98:
307                         case 0x99:
308                         case 0x9A:
309                         case 0x9B:
310                         case 0x9C:
311                         case 0x9D:
312                         case 0x9E:
313                         case 0x9F:
314                             hasDisp32 = true;
315                             // fall out of the switch to decode the Pointer
316                             break;
317 
318                         case 0xC4: // pinsrw r, a, #8
319                             hasDisp32 = true;
320                             tailSize = 1;  // the imm8
321                             break;
322 
323                         case 0xC5: // pextrw r, r, #8
324                             tailSize = 1;  // the imm8
325                             break;
326 
327                         case 0xAC: // shrd r, a, #8
328                             hasDisp32 = true;
329                             tailSize = 1; // the imm8
330                             break;
331 
332                         case 0x80: // jcc rdisp32
333                         case 0x81:
334                         case 0x82:
335                         case 0x83:
336                         case 0x84:
337                         case 0x85:
338                         case 0x86:
339                         case 0x87:
340                         case 0x88:
341                         case 0x89:
342                         case 0x8A:
343                         case 0x8B:
344                         case 0x8C:
345                         case 0x8D:
346                         case 0x8E:
347                         case 0x8F:
348                             currentEndOfInstruction = ip + 4;
349                             return;
350                         default:
351                             throw new InternalError("should not reach here");
352                     }
353                     break;
354 
355                 case 0x81: // addl a, #32; addl r, #32
356                     // also: orl, adcl, sbbl, andl, subl, xorl, cmpl
357                     // on 32bit in the case of cmpl, the imm might be an oop
358                     tailSize = 4;
359                     hasDisp32 = true; // has both kinds of operands!
360                     break;
361 
362                 case 0x83: // addl a, #8; addl r, #8
363                     // also: orl, adcl, sbbl, andl, subl, xorl, cmpl
364                     hasDisp32 = true; // has both kinds of operands!
365                     tailSize = 1;
366                     break;
367 
368                 case 0x9B:
369                     switch (0xFF & code[ip++]) {
370                         case 0xD9: // fnstcw a
371                             hasDisp32 = true;
372                             break;
373                         default:
374                             throw new InternalError("should not reach here");
375                     }
376                     break;
377 
378                 case 0x00: // addb a, r; addl a, r; addb r, a; addl r, a
379                 case 0x01:
380                 case 0x02:
381                 case 0x03:
382                 case 0x10: // adc...
383                 case 0x11:
384                 case 0x12:
385                 case 0x13:
386                 case 0x20: // and...
387                 case 0x21:
388                 case 0x22:
389                 case 0x23:
390                 case 0x30: // xor...
391                 case 0x31:
392                 case 0x32:
393                 case 0x33:
394                 case 0x08: // or...
395                 case 0x09:
396                 case 0x0a:
397                 case 0x0b:
398                 case 0x18: // sbb...
399                 case 0x19:
400                 case 0x1a:
401                 case 0x1b:
402                 case 0x28: // sub...
403                 case 0x29:
404                 case 0x2a:
405                 case 0x2b:
406                 case 0xF7: // mull a
407                 case 0x8D: // lea r, a
408                 case 0x87: // xchg r, a
409                 case 0x38: // cmp...
410                 case 0x39:
411                 case 0x3a:
412                 case 0x3b:
413                 case 0x85: // test r, a
414                     hasDisp32 = true; // has both kinds of operands!
415                     break;
416 
417                 case 0xC1: // sal a, #8; sar a, #8; shl a, #8; shr a, #8
418                 case 0xC6: // movb a, #8
419                 case 0x80: // cmpb a, #8
420                 case 0x6B: // imul r, a, #8
421                     hasDisp32 = true; // has both kinds of operands!
422                     tailSize = 1; // the imm8
423                     break;
424 
425                 case Prefix.VEX_3BYTES:
426                 case Prefix.VEX_2BYTES:
427                     assert ip == pcOffset + 1 : "no prefixes allowed";
428                     int vexOpcode;
429                     // First byte
430                     if ((code[pcOffset] & 0xFF) == Prefix.VEX_3BYTES) {
431                         vexOpcode = VexOpcode.VEX_OPCODE_MASK & code[ip];
432                         ip++; // third byte
433                         is64bit = ((VexPrefix.VEX_W & code[ip]) == VexPrefix.VEX_W);
434                     } else {
435                         vexOpcode = VexOpcode.VEX_OPCODE_0F;
436                     }
437                     ip++; // opcode
438                     // To find the end of instruction (which == end_pc_operand).
439                     switch (vexOpcode) {
440                         case VexOpcode.VEX_OPCODE_0F:
441                             switch (0xFF & code[ip]) {
442                                 case 0x70: // pshufd r, r/a, #8
443                                 case 0x71: // ps[rl|ra|ll]w r, #8
444                                 case 0x72: // ps[rl|ra|ll]d r, #8
445                                 case 0x73: // ps[rl|ra|ll]q r, #8
446                                 case 0xC2: // cmp[ps|pd|ss|sd] r, r, r/a, #8
447                                 case 0xC4: // pinsrw r, r, r/a, #8
448                                 case 0xC5: // pextrw r/a, r, #8
449                                 case 0xC6: // shufp[s|d] r, r, r/a, #8
450                                     tailSize = 1;  // the imm8
451                                     break;
452                                 default:
453                                     break; // no imm8
454                             }
455                             break;
456                         case VexOpcode.VEX_OPCODE_0F_3A:
457                             tailSize = 1;
458                             break;
459                         default:
460                             throw new InternalError("should not reach here");
461                     }
462                     ip++; // skip opcode
463                     hasDisp32 = true;
464                     break;
465 
466                 case 0xE8: // call rdisp32
467                 case 0xE9: // jmp rdisp32
468                     currentEndOfInstruction = ip + 4;
469                     return;
470 
471                 case 0xD1: // sal a, 1; sar a, 1; shl a, 1; shr a, 1
472                 case 0xD3: // sal a, %cl; sar a, %cl; shl a, %cl; shr a, %cl
473                 case 0xD9: // fldS a; fstS a; fstpS a; fldcw a
474                 case 0xDD: // fldD a; fstD a; fstpD a
475                 case 0xDB: // fildS a; fistpS a; fldX a; fstpX a
476                 case 0xDF: // fildD a; fistpD a
477                 case 0xD8: // faddS a; fsubrS a; fmulS a; fdivrS a; fcompS a
478                 case 0xDC: // faddD a; fsubrD a; fmulD a; fdivrD a; fcompD a
479                 case 0xDE: // faddpD a; fsubrpD a; fmulpD a; fdivrpD a; fcomppD a
480                     hasDisp32 = true;
481                     break;
482 
483                 case 0xF0: // Lock
484                     againAfterPrefix = true;
485                     break;
486 
487                 case 0xF3: // For SSE
488                 case 0xF2: // For SSE2
489                     switch (0xFF & code[ip++]) {
490                         case Prefix.REX:
491                         case Prefix.REXB:
492                         case Prefix.REXX:
493                         case Prefix.REXXB:
494                         case Prefix.REXR:
495                         case Prefix.REXRB:
496                         case Prefix.REXRX:
497                         case Prefix.REXRXB:
498                         case Prefix.REXW:
499                         case Prefix.REXWB:
500                         case Prefix.REXWX:
501                         case Prefix.REXWXB:
502                         case Prefix.REXWR:
503                         case Prefix.REXWRB:
504                         case Prefix.REXWRX:
505                         case Prefix.REXWRXB:
506                             assert targetIs64Bit : "found 64bit prefix";
507                             ip++;
508                             ip++;
509                             break;
510                         default:
511                             ip++;
512                     }
513                     hasDisp32 = true; // has both kinds of operands!
514                     break;
515 
516                 default:
517                     throw new InternalError("should not reach here");
518             }
519         }
520 
521         assert hasDisp32 : "(tw) not sure if this holds: instruction has no disp32 field";
522 
523         // parse the output of emitOperand
524         int op2 = 0xFF & code[ip++];
525         int base = op2 & 0x07;
526         int op3 = -1;
527         int b100 = 4;
528         int b101 = 5;
529         if (base == b100 && (op2 >> 6) != 3) {
530             op3 = 0xFF & code[ip++];
531             base = op3 & 0x07; // refetch the base
532         }
533         // now ip points at the disp (if any)
534 
535         switch (op2 >> 6) {
536             case 0:
537                 // [00 reg 100][ss index base]
538                 // [00 reg 100][00 100 esp]
539                 // [00 reg base]
540                 // [00 reg 100][ss index 101][disp32]
541                 // [00 reg 101] [disp32]
542                 if (base == b101) {
543                     ip += 4; // skip the disp32
544                 }
545                 break;
546 
547             case 1:
548                 // [01 reg 100][ss index base][disp8]
549                 // [01 reg 100][00 100 esp][disp8]
550                 // [01 reg base] [disp8]
551                 ip += 1; // skip the disp8
552                 break;
553 
554             case 2:
555                 // [10 reg 100][ss index base][disp32]
556                 // [10 reg 100][00 100 esp][disp32]
557                 // [10 reg base] [disp32]
558                 ip += 4; // skip the disp32
559                 break;
560 
561             case 3:
562                 // [11 reg base] (not a memory addressing mode)
563                 break;
564         }
565 
566         currentEndOfInstruction = ip + tailSize;
567     }
568 
569 }
570