OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /* | 7 /* |
8 * Hand-written Ragel machines and actions used in validator and decoding. | 8 * Hand-written Ragel machines and actions used in validator and decoding. |
9 * | 9 * |
10 * Note: this file includes many different machines which are supposed to be | 10 * Note: this file includes many different machines which are supposed to be |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 VEX_RX = b_xx1_xxxxx @vex_prefix2; | 243 VEX_RX = b_xx1_xxxxx @vex_prefix2; |
244 VEX_RB = b_x1x_xxxxx @vex_prefix2; | 244 VEX_RB = b_x1x_xxxxx @vex_prefix2; |
245 VEX_XB = b_1xx_xxxxx @vex_prefix2; | 245 VEX_XB = b_1xx_xxxxx @vex_prefix2; |
246 VEX_RXB = b_xxx_xxxxx @vex_prefix2; | 246 VEX_RXB = b_xxx_xxxxx @vex_prefix2; |
247 }%% | 247 }%% |
248 | 248 |
249 %%{ | 249 %%{ |
250 machine modrm_actions_ia32; | 250 machine modrm_actions_ia32; |
251 | 251 |
252 action modrm_only_base { | 252 action modrm_only_base { |
253 SET_DISP_TYPE(DISPNONE); | 253 SET_DISPLACEMENT_FORMAT(DISPNONE); |
254 SET_MODRM_BASE(RMFromModRM(*current_position)); | 254 SET_MODRM_BASE(RMFromModRM(*current_position)); |
255 SET_MODRM_INDEX(NO_REG); | 255 SET_MODRM_INDEX(NO_REG); |
256 SET_MODRM_SCALE(0); | 256 SET_MODRM_SCALE(0); |
257 } | 257 } |
258 action modrm_base_disp { | 258 action modrm_base_disp { |
259 SET_MODRM_BASE(RMFromModRM(*current_position)); | 259 SET_MODRM_BASE(RMFromModRM(*current_position)); |
260 SET_MODRM_INDEX(NO_REG); | 260 SET_MODRM_INDEX(NO_REG); |
261 SET_MODRM_SCALE(0); | 261 SET_MODRM_SCALE(0); |
262 } | 262 } |
263 action modrm_pure_disp { | 263 action modrm_pure_disp { |
264 // Case where ModRM.mod = 00 and ModRM.r/m = 101. | 264 // Case where ModRM.mod = 00 and ModRM.r/m = 101. |
265 SET_MODRM_BASE(NO_REG); | 265 SET_MODRM_BASE(NO_REG); |
266 SET_MODRM_INDEX(NO_REG); | 266 SET_MODRM_INDEX(NO_REG); |
267 SET_MODRM_SCALE(0); | 267 SET_MODRM_SCALE(0); |
268 } | 268 } |
269 action modrm_pure_index { | 269 action modrm_pure_index { |
270 SET_DISP_TYPE(DISPNONE); | 270 SET_DISPLACEMENT_FORMAT(DISPNONE); |
271 SET_MODRM_BASE(NO_REG); | 271 SET_MODRM_BASE(NO_REG); |
272 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position)]); | 272 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position)]); |
273 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); | 273 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); |
274 } | 274 } |
275 action modrm_parse_sib { | 275 action modrm_parse_sib { |
276 SET_DISP_TYPE(DISPNONE); | 276 SET_DISPLACEMENT_FORMAT(DISPNONE); |
277 SET_MODRM_BASE(BaseFromSIB(*current_position)); | 277 SET_MODRM_BASE(BaseFromSIB(*current_position)); |
278 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position)]); | 278 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position)]); |
279 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); | 279 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); |
280 } | 280 } |
281 }%% | 281 }%% |
282 | 282 |
283 %%{ | 283 %%{ |
284 machine modrm_actions_amd64; | 284 machine modrm_actions_amd64; |
285 | 285 |
286 action modrm_only_base { | 286 action modrm_only_base { |
287 SET_DISP_TYPE(DISPNONE); | 287 SET_DISPLACEMENT_FORMAT(DISPNONE); |
288 SET_MODRM_BASE(BaseFromSIB(*current_position) | | 288 SET_MODRM_BASE(BaseFromSIB(*current_position) | |
289 BaseExtentionFromREX(GET_REX_PREFIX()) | | 289 BaseExtentionFromREX(GET_REX_PREFIX()) | |
290 BaseExtentionFromVEX(GET_VEX_PREFIX2())); | 290 BaseExtentionFromVEX(GET_VEX_PREFIX2())); |
291 SET_MODRM_INDEX(NO_REG); | 291 SET_MODRM_INDEX(NO_REG); |
292 SET_MODRM_SCALE(0); | 292 SET_MODRM_SCALE(0); |
293 } | 293 } |
294 action modrm_base_disp { | 294 action modrm_base_disp { |
295 SET_MODRM_BASE(BaseFromSIB(*current_position) | | 295 SET_MODRM_BASE(BaseFromSIB(*current_position) | |
296 BaseExtentionFromREX(GET_REX_PREFIX()) | | 296 BaseExtentionFromREX(GET_REX_PREFIX()) | |
297 BaseExtentionFromVEX(GET_VEX_PREFIX2())); | 297 BaseExtentionFromVEX(GET_VEX_PREFIX2())); |
298 SET_MODRM_INDEX(NO_REG); | 298 SET_MODRM_INDEX(NO_REG); |
299 SET_MODRM_SCALE(0); | 299 SET_MODRM_SCALE(0); |
300 } | 300 } |
301 action modrm_pure_disp { | 301 action modrm_pure_disp { |
302 // Case where ModRM.mod = 00 and ModRM.r/m = 101. | 302 // Case where ModRM.mod = 00 and ModRM.r/m = 101. |
303 // In 64-bit mode it corresponds to RIP-relative addressing. | 303 // In 64-bit mode it corresponds to RIP-relative addressing. |
304 SET_MODRM_BASE(REG_RIP); | 304 SET_MODRM_BASE(REG_RIP); |
305 SET_MODRM_INDEX(NO_REG); | 305 SET_MODRM_INDEX(NO_REG); |
306 SET_MODRM_SCALE(0); | 306 SET_MODRM_SCALE(0); |
307 } | 307 } |
308 action modrm_pure_index { | 308 action modrm_pure_index { |
309 SET_DISP_TYPE(DISPNONE); | 309 SET_DISPLACEMENT_FORMAT(DISPNONE); |
310 SET_MODRM_BASE(NO_REG); | 310 SET_MODRM_BASE(NO_REG); |
311 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position) | | 311 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position) | |
312 IndexExtentionFromREX(GET_REX_PREFIX()) | | 312 IndexExtentionFromREX(GET_REX_PREFIX()) | |
313 IndexExtentionFromVEX(GET_VEX_PREFIX2())]); | 313 IndexExtentionFromVEX(GET_VEX_PREFIX2())]); |
314 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); | 314 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); |
315 } | 315 } |
316 action modrm_parse_sib { | 316 action modrm_parse_sib { |
317 SET_DISP_TYPE(DISPNONE); | 317 SET_DISPLACEMENT_FORMAT(DISPNONE); |
318 SET_MODRM_BASE(BaseFromSIB(*current_position) | | 318 SET_MODRM_BASE(BaseFromSIB(*current_position) | |
319 BaseExtentionFromREX(GET_REX_PREFIX()) | | 319 BaseExtentionFromREX(GET_REX_PREFIX()) | |
320 BaseExtentionFromVEX(GET_VEX_PREFIX2())); | 320 BaseExtentionFromVEX(GET_VEX_PREFIX2())); |
321 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position) | | 321 SET_MODRM_INDEX(index_registers[IndexFromSIB(*current_position) | |
322 IndexExtentionFromREX(GET_REX_PREFIX()) | | 322 IndexExtentionFromREX(GET_REX_PREFIX()) | |
323 IndexExtentionFromVEX(GET_VEX_PREFIX2())]); | 323 IndexExtentionFromVEX(GET_VEX_PREFIX2())]); |
324 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); | 324 SET_MODRM_SCALE(ScaleFromSIB(*current_position)); |
325 } | 325 } |
326 }%% | 326 }%% |
327 | 327 |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 SET_OPERAND_NAME(3, RMFromModRM(*current_position) | | 649 SET_OPERAND_NAME(3, RMFromModRM(*current_position) | |
650 BaseExtentionFromREX(GET_REX_PREFIX()) | | 650 BaseExtentionFromREX(GET_REX_PREFIX()) | |
651 BaseExtentionFromVEX(GET_VEX_PREFIX2())); | 651 BaseExtentionFromVEX(GET_VEX_PREFIX2())); |
652 } | 652 } |
653 }%% | 653 }%% |
654 | 654 |
655 %%{ | 655 %%{ |
656 machine displacement_fields_parsing; | 656 machine displacement_fields_parsing; |
657 | 657 |
658 action disp8_operand { | 658 action disp8_operand { |
659 SET_DISP_TYPE(DISP8); | 659 SET_DISPLACEMENT_FORMAT(DISP8); |
660 SET_DISP_PTR(current_position); | 660 SET_DISPLACEMENT_POINTER(current_position); |
661 } | 661 } |
662 action disp32_operand { | 662 action disp32_operand { |
663 SET_DISP_TYPE(DISP32); | 663 SET_DISPLACEMENT_FORMAT(DISP32); |
664 SET_DISP_PTR(current_position - 3); | 664 SET_DISPLACEMENT_POINTER(current_position - 3); |
665 } | 665 } |
666 action disp64_operand { | 666 action disp64_operand { |
667 SET_DISP_TYPE(DISP64); | 667 SET_DISPLACEMENT_FORMAT(DISP64); |
668 SET_DISP_PTR(current_position - 7); | 668 SET_DISPLACEMENT_POINTER(current_position - 7); |
669 } | 669 } |
670 | 670 |
671 # This action is used to mark transitions corresponding to immediates, | 671 # This action is used to mark transitions corresponding to immediates, |
672 # displacements and relative jump targets - stuff that we don't have to | 672 # displacements and relative jump targets - stuff that we don't have to |
673 # enumerate in enumeration tests. | 673 # enumerate in enumeration tests. |
674 # TODO(shcherbina): find appropriate place for this action. | 674 # TODO(shcherbina): find appropriate place for this action. |
675 action any_byte {} | 675 action any_byte {} |
676 | 676 |
677 disp8 = any @disp8_operand $any_byte; | 677 disp8 = any @disp8_operand $any_byte; |
678 disp32 = any{4} @disp32_operand $any_byte; | 678 disp32 = any{4} @disp32_operand $any_byte; |
679 disp64 = any{8} @disp64_operand $any_byte; | 679 disp64 = any{8} @disp64_operand $any_byte; |
680 }%% | 680 }%% |
681 | 681 |
682 %%{ | 682 %%{ |
683 machine immediate_fields_parsing; | 683 machine immediate_fields_parsing; |
684 | 684 |
685 action imm2_operand { | 685 action imm2_operand { |
686 SET_IMM_TYPE(IMM2); | 686 SET_IMMEDIATE_FORMAT(IMM2); |
687 SET_IMM_PTR(current_position); | 687 SET_IMMEDIATE_POINTER(current_position); |
688 } | 688 } |
689 action imm8_operand { | 689 action imm8_operand { |
690 SET_IMM_TYPE(IMM8); | 690 SET_IMMEDIATE_FORMAT(IMM8); |
691 SET_IMM_PTR(current_position); | 691 SET_IMMEDIATE_POINTER(current_position); |
692 } | 692 } |
693 action imm8_second_operand { | 693 action imm8_second_operand { |
694 SET_IMM2_TYPE(IMM8); | 694 SET_SECOND_IMMEDIATE_FORMAT(IMM8); |
695 SET_IMM2_PTR(current_position); | 695 SET_SECOND_IMMEDIATE_POINTER(current_position); |
696 } | 696 } |
697 action imm16_operand { | 697 action imm16_operand { |
698 SET_IMM_TYPE(IMM16); | 698 SET_IMMEDIATE_FORMAT(IMM16); |
699 SET_IMM_PTR(current_position - 1); | 699 SET_IMMEDIATE_POINTER(current_position - 1); |
700 } | 700 } |
701 action imm16_second_operand { | 701 action imm16_second_operand { |
702 SET_IMM2_TYPE(IMM16); | 702 SET_SECOND_IMMEDIATE_FORMAT(IMM16); |
703 SET_IMM2_PTR(current_position - 1); | 703 SET_SECOND_IMMEDIATE_POINTER(current_position - 1); |
704 } | 704 } |
705 action imm32_operand { | 705 action imm32_operand { |
706 SET_IMM_TYPE(IMM32); | 706 SET_IMMEDIATE_FORMAT(IMM32); |
707 SET_IMM_PTR(current_position - 3); | 707 SET_IMMEDIATE_POINTER(current_position - 3); |
708 } | 708 } |
709 action imm32_second_operand { | 709 action imm32_second_operand { |
710 SET_IMM2_TYPE(IMM32); | 710 SET_SECOND_IMMEDIATE_FORMAT(IMM32); |
711 SET_IMM2_PTR(current_position - 3); | 711 SET_SECOND_IMMEDIATE_POINTER(current_position - 3); |
712 } | 712 } |
713 action imm64_operand { | 713 action imm64_operand { |
714 SET_IMM_TYPE(IMM64); | 714 SET_IMMEDIATE_FORMAT(IMM64); |
715 SET_IMM_PTR(current_position - 7); | 715 SET_IMMEDIATE_POINTER(current_position - 7); |
716 } | 716 } |
717 action imm64_second_operand { | 717 action imm64_second_operand { |
718 SET_IMM2_TYPE(IMM64); | 718 SET_SECOND_IMMEDIATE_FORMAT(IMM64); |
719 SET_IMM2_PTR(current_position - 7); | 719 SET_SECOND_IMMEDIATE_POINTER(current_position - 7); |
720 } | 720 } |
721 | 721 |
722 imm8 = any @imm8_operand $any_byte; | 722 imm8 = any @imm8_operand $any_byte; |
723 imm16 = any{2} @imm16_operand $any_byte; | 723 imm16 = any{2} @imm16_operand $any_byte; |
724 imm32 = any{4} @imm32_operand $any_byte; | 724 imm32 = any{4} @imm32_operand $any_byte; |
725 imm64 = any{8} @imm64_operand $any_byte; | 725 imm64 = any{8} @imm64_operand $any_byte; |
726 imm8n2 = any @imm8_second_operand $any_byte; | 726 imm8n2 = any @imm8_second_operand $any_byte; |
727 imm16n2 = any{2} @imm16_second_operand $any_byte; | 727 imm16n2 = any{2} @imm16_second_operand $any_byte; |
728 }%% | 728 }%% |
729 | 729 |
730 %%{ | 730 %%{ |
731 machine relative_fields_decoder_actions; | 731 machine relative_fields_decoder_actions; |
732 | 732 |
733 action rel8_operand { | 733 action rel8_operand { |
734 SET_MODRM_BASE(REG_RIP); | 734 SET_MODRM_BASE(REG_RIP); |
735 SET_MODRM_INDEX(NO_REG); | 735 SET_MODRM_INDEX(NO_REG); |
736 SET_MODRM_SCALE(0); | 736 SET_MODRM_SCALE(0); |
737 SET_DISP_TYPE(DISP8); | 737 SET_DISPLACEMENT_FORMAT(DISP8); |
738 SET_DISP_PTR(current_position); | 738 SET_DISPLACEMENT_POINTER(current_position); |
739 } | 739 } |
740 action rel16_operand { | 740 action rel16_operand { |
741 SET_MODRM_BASE(REG_RIP); | 741 SET_MODRM_BASE(REG_RIP); |
742 SET_MODRM_INDEX(NO_REG); | 742 SET_MODRM_INDEX(NO_REG); |
743 SET_MODRM_SCALE(0); | 743 SET_MODRM_SCALE(0); |
744 SET_DISP_TYPE(DISP16); | 744 SET_DISPLACEMENT_FORMAT(DISP16); |
745 SET_DISP_PTR(current_position - 1); | 745 SET_DISPLACEMENT_POINTER(current_position - 1); |
746 } | 746 } |
747 action rel32_operand { | 747 action rel32_operand { |
748 SET_MODRM_BASE(REG_RIP); | 748 SET_MODRM_BASE(REG_RIP); |
749 SET_MODRM_INDEX(NO_REG); | 749 SET_MODRM_INDEX(NO_REG); |
750 SET_MODRM_SCALE(0); | 750 SET_MODRM_SCALE(0); |
751 SET_DISP_TYPE(DISP32); | 751 SET_DISPLACEMENT_FORMAT(DISP32); |
752 SET_DISP_PTR(current_position - 3); | 752 SET_DISPLACEMENT_POINTER(current_position - 3); |
753 } | 753 } |
754 }%% | 754 }%% |
755 | 755 |
756 %%{ | 756 %%{ |
757 machine relative_fields_validator_actions; | 757 machine relative_fields_validator_actions; |
758 | 758 |
759 # rel8 actions are used in relative jumps with 8-bit offset. | 759 # rel8 actions are used in relative jumps with 8-bit offset. |
760 action rel8_operand { | 760 action rel8_operand { |
761 Rel8Operand(current_position + 1, data, jump_dests, size, | 761 Rel8Operand(current_position + 1, codeblock, jump_dests, size, |
762 &instruction_info_collected); | 762 &instruction_info_collected); |
763 } | 763 } |
764 | 764 |
765 # rel16 actions are used in relative jumps with 16-bit offset. | 765 # rel16 actions are used in relative jumps with 16-bit offset. |
766 # Such instructions should not be included in the validator's DFA, but we can | 766 # Such instructions should not be included in the validator's DFA, but we can |
767 # not just exclude them because they are refenced in relative_fields_parsing | 767 # not just exclude them because they are refenced in relative_fields_parsing |
768 # ragel machine. Ensure compilations error in case of accidental usage. | 768 # ragel machine. Ensure compilations error in case of accidental usage. |
769 action rel16_operand { | 769 action rel16_operand { |
770 #error rel16_operand should never be used in nacl | 770 #error rel16_operand should never be used in nacl |
771 } | 771 } |
772 | 772 |
773 # rel32 actions are used in relative calls and jumps with 32-bit offset. | 773 # rel32 actions are used in relative calls and jumps with 32-bit offset. |
774 action rel32_operand { | 774 action rel32_operand { |
775 Rel32Operand(current_position + 1, data, jump_dests, size, | 775 Rel32Operand(current_position + 1, codeblock, jump_dests, size, |
776 &instruction_info_collected); | 776 &instruction_info_collected); |
777 } | 777 } |
| 778 |
| 779 # Action which marks last byte as not immediate. Most 3DNow! instructions, |
| 780 # some AVX and XOP instructions have this property. |
| 781 # |
| 782 # This action is referenced by decode_x86_32 ragel machine in [autogenerated] |
| 783 # "validator_x86_32_instruction.rl" file. |
| 784 action last_byte_is_not_immediate { |
| 785 instruction_info_collected |= LAST_BYTE_IS_NOT_IMMEDIATE; |
| 786 } |
778 }%% | 787 }%% |
779 | 788 |
780 %%{ | 789 %%{ |
781 machine relative_fields_parsing; | 790 machine relative_fields_parsing; |
782 | 791 |
783 rel8 = any @rel8_operand $any_byte; | 792 rel8 = any @rel8_operand $any_byte; |
784 rel16 = any{2} @rel16_operand $any_byte; | 793 rel16 = any{2} @rel16_operand $any_byte; |
785 rel32 = any{4} @rel32_operand $any_byte; | 794 rel32 = any{4} @rel32_operand $any_byte; |
786 }%% | 795 }%% |
787 | 796 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
843 action att_show_name_suffix_b { SET_ATT_INSTRUCTION_SUFFIX("b"); } | 852 action att_show_name_suffix_b { SET_ATT_INSTRUCTION_SUFFIX("b"); } |
844 action att_show_name_suffix_l { SET_ATT_INSTRUCTION_SUFFIX("l"); } | 853 action att_show_name_suffix_l { SET_ATT_INSTRUCTION_SUFFIX("l"); } |
845 action att_show_name_suffix_ll { SET_ATT_INSTRUCTION_SUFFIX("ll"); } | 854 action att_show_name_suffix_ll { SET_ATT_INSTRUCTION_SUFFIX("ll"); } |
846 action att_show_name_suffix_t { SET_ATT_INSTRUCTION_SUFFIX("t"); } | 855 action att_show_name_suffix_t { SET_ATT_INSTRUCTION_SUFFIX("t"); } |
847 action att_show_name_suffix_s { SET_ATT_INSTRUCTION_SUFFIX("s"); } | 856 action att_show_name_suffix_s { SET_ATT_INSTRUCTION_SUFFIX("s"); } |
848 action att_show_name_suffix_q { SET_ATT_INSTRUCTION_SUFFIX("q"); } | 857 action att_show_name_suffix_q { SET_ATT_INSTRUCTION_SUFFIX("q"); } |
849 action att_show_name_suffix_w { SET_ATT_INSTRUCTION_SUFFIX("w"); } | 858 action att_show_name_suffix_w { SET_ATT_INSTRUCTION_SUFFIX("w"); } |
850 action att_show_name_suffix_x { SET_ATT_INSTRUCTION_SUFFIX("x"); } | 859 action att_show_name_suffix_x { SET_ATT_INSTRUCTION_SUFFIX("x"); } |
851 action att_show_name_suffix_y { SET_ATT_INSTRUCTION_SUFFIX("y"); } | 860 action att_show_name_suffix_y { SET_ATT_INSTRUCTION_SUFFIX("y"); } |
852 }%% | 861 }%% |
OLD | NEW |