1e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/* 2e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Copyright (C) 2012 The Android Open Source Project 3e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 4e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Licensed under the Apache License, Version 2.0 (the "License"); 5e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * you may not use this file except in compliance with the License. 6e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * You may obtain a copy of the License at 7e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 8e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * http://www.apache.org/licenses/LICENSE-2.0 9e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * 10e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Unless required by applicable law or agreed to in writing, software 11e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * distributed under the License is distributed on an "AS IS" BASIS, 12e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * See the License for the specific language governing permissions and 14e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * limitations under the License. 15e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */ 16e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1702031b185b4653e6c72e21f7a51238b903f6d638buzbee#include "codegen_x86.h" 187940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/quick/mir_to_lir-inl.h" 19641ce0371c2f0dc95d26be02d8366124c8b66653Brian Carlstrom#include "x86_lir.h" 20e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 21e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbeenamespace art { 22e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 23e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee#define MAX_ASSEMBLER_RETRIES 50 24e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 251fd3346740dfb7f47be9922312b68a4227fada96buzbeeconst X86EncodingMap X86Mir2Lir::EncodingMap[kX86Last] = { 260f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX8632BitData, kData, IS_UNARY_OP, { 0, 0, 0x00, 0, 0, 0, 0, 4, false }, "data", "0x!0d" }, 270f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Bkpt, kNullary, NO_OPERAND | IS_BRANCH, { 0, 0, 0xCC, 0, 0, 0, 0, 0, false }, "int 3", "" }, 280f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Nop, kNop, NO_OPERAND, { 0, 0, 0x90, 0, 0, 0, 0, 0, false }, "nop", "" }, 29b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 30e296248a124ed8287b38a9225463696c18d84cd6jeffhao#define ENCODING_MAP(opname, mem_use, reg_def, uses_ccodes, \ 31b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers rm8_r8, rm32_r32, \ 32b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers r8_rm8, r32_rm32, \ 33b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers ax8_i8, ax32_i32, \ 34b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers rm8_i8, rm8_i8_modrm, \ 35b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers rm32_i32, rm32_i32_modrm, \ 36b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers rm32_i8, rm32_i8_modrm) \ 370f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8MR, kMemReg, mem_use | IS_TERTIARY_OP | REG_USE02 | SETS_CCODES | uses_ccodes, { 0, 0, rm8_r8, 0, 0, 0, 0, 0, true }, #opname "8MR", "[!0r+!1d],!2r" }, \ 382bc477043b6ab2d7b4719ba8debf0a6a5b10c225Mark Mendell{ kX86 ## opname ## 8AR, kArrayReg, mem_use | IS_QUIN_OP | REG_USE014 | SETS_CCODES | uses_ccodes, { 0, 0, rm8_r8, 0, 0, 0, 0, 0, true }, #opname "8AR", "[!0r+!1r<<!2d+!3d],!4r" }, \ 390f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8TR, kThreadReg, mem_use | IS_BINARY_OP | REG_USE1 | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0, rm8_r8, 0, 0, 0, 0, 0, true }, #opname "8TR", "fs:[!0d],!1r" }, \ 400f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8RR, kRegReg, IS_BINARY_OP | reg_def | REG_USE01 | SETS_CCODES | uses_ccodes, { 0, 0, r8_rm8, 0, 0, 0, 0, 0, true }, #opname "8RR", "!0r,!1r" }, \ 410f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE01 | SETS_CCODES | uses_ccodes, { 0, 0, r8_rm8, 0, 0, 0, 0, 0, true }, #opname "8RM", "!0r,[!1r+!2d]" }, \ 420f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8RA, kRegArray, IS_LOAD | IS_QUIN_OP | reg_def | REG_USE012 | SETS_CCODES | uses_ccodes, { 0, 0, r8_rm8, 0, 0, 0, 0, 0, true }, #opname "8RA", "!0r,[!1r+!2r<<!3d+!4d]" }, \ 430f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8RT, kRegThread, IS_LOAD | IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0, r8_rm8, 0, 0, 0, 0, 0, true }, #opname "8RT", "!0r,fs:[!1d]" }, \ 440f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8RI, kRegImm, IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { 0, 0, rm8_i8, 0, 0, rm8_i8_modrm, ax8_i8, 1, true }, #opname "8RI", "!0r,!1d" }, \ 45fd0c237e7d80ad567399e760203f3cda404bf4c5Mark Mendell{ kX86 ## opname ## 8MI, kMemImm, mem_use | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES | uses_ccodes, { 0, 0, rm8_i8, 0, 0, rm8_i8_modrm, 0, 1, false}, #opname "8MI", "[!0r+!1d],!2d" }, \ 46fd0c237e7d80ad567399e760203f3cda404bf4c5Mark Mendell{ kX86 ## opname ## 8AI, kArrayImm, mem_use | IS_QUIN_OP | REG_USE01 | SETS_CCODES | uses_ccodes, { 0, 0, rm8_i8, 0, 0, rm8_i8_modrm, 0, 1, false}, #opname "8AI", "[!0r+!1r<<!2d+!3d],!4d" }, \ 47fd0c237e7d80ad567399e760203f3cda404bf4c5Mark Mendell{ kX86 ## opname ## 8TI, kThreadImm, mem_use | IS_BINARY_OP | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0, rm8_i8, 0, 0, rm8_i8_modrm, 0, 1, false}, #opname "8TI", "fs:[!0d],!1d" }, \ 48b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers \ 490f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16MR, kMemReg, mem_use | IS_TERTIARY_OP | REG_USE02 | SETS_CCODES | uses_ccodes, { 0x66, 0, rm32_r32, 0, 0, 0, 0, 0, false }, #opname "16MR", "[!0r+!1d],!2r" }, \ 500f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16AR, kArrayReg, mem_use | IS_QUIN_OP | REG_USE014 | SETS_CCODES | uses_ccodes, { 0x66, 0, rm32_r32, 0, 0, 0, 0, 0, false }, #opname "16AR", "[!0r+!1r<<!2d+!3d],!4r" }, \ 510f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16TR, kThreadReg, mem_use | IS_BINARY_OP | REG_USE1 | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0x66, rm32_r32, 0, 0, 0, 0, 0, false }, #opname "16TR", "fs:[!0d],!1r" }, \ 520f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16RR, kRegReg, IS_BINARY_OP | reg_def | REG_USE01 | SETS_CCODES | uses_ccodes, { 0x66, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "16RR", "!0r,!1r" }, \ 530f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE01 | SETS_CCODES | uses_ccodes, { 0x66, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "16RM", "!0r,[!1r+!2d]" }, \ 540f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16RA, kRegArray, IS_LOAD | IS_QUIN_OP | reg_def | REG_USE012 | SETS_CCODES | uses_ccodes, { 0x66, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "16RA", "!0r,[!1r+!2r<<!3d+!4d]" }, \ 550f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16RT, kRegThread, IS_LOAD | IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0x66, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "16RT", "!0r,fs:[!1d]" }, \ 560f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16RI, kRegImm, IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { 0x66, 0, rm32_i32, 0, 0, rm32_i32_modrm, ax32_i32, 2, false }, #opname "16RI", "!0r,!1d" }, \ 570f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16MI, kMemImm, mem_use | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES | uses_ccodes, { 0x66, 0, rm32_i32, 0, 0, rm32_i32_modrm, 0, 2, false }, #opname "16MI", "[!0r+!1d],!2d" }, \ 580f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16AI, kArrayImm, mem_use | IS_QUIN_OP | REG_USE01 | SETS_CCODES | uses_ccodes, { 0x66, 0, rm32_i32, 0, 0, rm32_i32_modrm, 0, 2, false }, #opname "16AI", "[!0r+!1r<<!2d+!3d],!4d" }, \ 590f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16TI, kThreadImm, mem_use | IS_BINARY_OP | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0x66, rm32_i32, 0, 0, rm32_i32_modrm, 0, 2, false }, #opname "16TI", "fs:[!0d],!1d" }, \ 600f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16RI8, kRegImm, IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { 0x66, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "16RI8", "!0r,!1d" }, \ 610f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16MI8, kMemImm, mem_use | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES | uses_ccodes, { 0x66, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "16MI8", "[!0r+!1d],!2d" }, \ 620f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16AI8, kArrayImm, mem_use | IS_QUIN_OP | REG_USE01 | SETS_CCODES | uses_ccodes, { 0x66, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "16AI8", "[!0r+!1r<<!2d+!3d],!4d" }, \ 630f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16TI8, kThreadImm, mem_use | IS_BINARY_OP | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0x66, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "16TI8", "fs:[!0d],!1d" }, \ 64b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers \ 650f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32MR, kMemReg, mem_use | IS_TERTIARY_OP | REG_USE02 | SETS_CCODES | uses_ccodes, { 0, 0, rm32_r32, 0, 0, 0, 0, 0, false }, #opname "32MR", "[!0r+!1d],!2r" }, \ 660f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32AR, kArrayReg, mem_use | IS_QUIN_OP | REG_USE014 | SETS_CCODES | uses_ccodes, { 0, 0, rm32_r32, 0, 0, 0, 0, 0, false }, #opname "32AR", "[!0r+!1r<<!2d+!3d],!4r" }, \ 670f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32TR, kThreadReg, mem_use | IS_BINARY_OP | REG_USE1 | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0, rm32_r32, 0, 0, 0, 0, 0, false }, #opname "32TR", "fs:[!0d],!1r" }, \ 680f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32RR, kRegReg, IS_BINARY_OP | reg_def | REG_USE01 | SETS_CCODES | uses_ccodes, { 0, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "32RR", "!0r,!1r" }, \ 690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE01 | SETS_CCODES | uses_ccodes, { 0, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "32RM", "!0r,[!1r+!2d]" }, \ 700f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32RA, kRegArray, IS_LOAD | IS_QUIN_OP | reg_def | REG_USE012 | SETS_CCODES | uses_ccodes, { 0, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "32RA", "!0r,[!1r+!2r<<!3d+!4d]" }, \ 710f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32RT, kRegThread, IS_LOAD | IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "32RT", "!0r,fs:[!1d]" }, \ 720f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32RI, kRegImm, IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { 0, 0, rm32_i32, 0, 0, rm32_i32_modrm, ax32_i32, 4, false }, #opname "32RI", "!0r,!1d" }, \ 730f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32MI, kMemImm, mem_use | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES | uses_ccodes, { 0, 0, rm32_i32, 0, 0, rm32_i32_modrm, 0, 4, false }, #opname "32MI", "[!0r+!1d],!2d" }, \ 740f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32AI, kArrayImm, mem_use | IS_QUIN_OP | REG_USE01 | SETS_CCODES | uses_ccodes, { 0, 0, rm32_i32, 0, 0, rm32_i32_modrm, 0, 4, false }, #opname "32AI", "[!0r+!1r<<!2d+!3d],!4d" }, \ 750f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32TI, kThreadImm, mem_use | IS_BINARY_OP | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0, rm32_i32, 0, 0, rm32_i32_modrm, 0, 4, false }, #opname "32TI", "fs:[!0d],!1d" }, \ 760f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32RI8, kRegImm, IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { 0, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "32RI8", "!0r,!1d" }, \ 770f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32MI8, kMemImm, mem_use | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES | uses_ccodes, { 0, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "32MI8", "[!0r+!1d],!2d" }, \ 780f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32AI8, kArrayImm, mem_use | IS_QUIN_OP | REG_USE01 | SETS_CCODES | uses_ccodes, { 0, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "32AI8", "[!0r+!1r<<!2d+!3d],!4d" }, \ 790f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32TI8, kThreadImm, mem_use | IS_BINARY_OP | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "32TI8", "fs:[!0d],!1d" }, \ 8096992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko \ 810f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64MR, kMemReg, mem_use | IS_TERTIARY_OP | REG_USE02 | SETS_CCODES | uses_ccodes, { REX_W, 0, rm32_r32, 0, 0, 0, 0, 0, false }, #opname "64MR", "[!0r+!1d],!2r" }, \ 820f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64AR, kArrayReg, mem_use | IS_QUIN_OP | REG_USE014 | SETS_CCODES | uses_ccodes, { REX_W, 0, rm32_r32, 0, 0, 0, 0, 0, false }, #opname "64AR", "[!0r+!1r<<!2d+!3d],!4r" }, \ 830f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64TR, kThreadReg, mem_use | IS_BINARY_OP | REG_USE1 | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, REX_W, rm32_r32, 0, 0, 0, 0, 0, false }, #opname "64TR", "fs:[!0d],!1r" }, \ 840f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64RR, kRegReg, IS_BINARY_OP | reg_def | REG_USE01 | SETS_CCODES | uses_ccodes, { REX_W, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "64RR", "!0r,!1r" }, \ 850f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE01 | SETS_CCODES | uses_ccodes, { REX_W, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "64RM", "!0r,[!1r+!2d]" }, \ 860f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64RA, kRegArray, IS_LOAD | IS_QUIN_OP | reg_def | REG_USE012 | SETS_CCODES | uses_ccodes, { REX_W, 0, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "64RA", "!0r,[!1r+!2r<<!3d+!4d]" }, \ 870f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64RT, kRegThread, IS_LOAD | IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, REX_W, r32_rm32, 0, 0, 0, 0, 0, false }, #opname "64RT", "!0r,fs:[!1d]" }, \ 880f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64RI, kRegImm, IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { REX_W, 0, rm32_i32, 0, 0, rm32_i32_modrm, ax32_i32, 4, false }, #opname "64RI", "!0r,!1d" }, \ 890f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64MI, kMemImm, mem_use | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES | uses_ccodes, { REX_W, 0, rm32_i32, 0, 0, rm32_i32_modrm, 0, 4, false }, #opname "64MI", "[!0r+!1d],!2d" }, \ 900f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64AI, kArrayImm, mem_use | IS_QUIN_OP | REG_USE01 | SETS_CCODES | uses_ccodes, { REX_W, 0, rm32_i32, 0, 0, rm32_i32_modrm, 0, 4, false }, #opname "64AI", "[!0r+!1r<<!2d+!3d],!4d" }, \ 910f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64TI, kThreadImm, mem_use | IS_BINARY_OP | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, REX_W, rm32_i32, 0, 0, rm32_i32_modrm, 0, 4, false }, #opname "64TI", "fs:[!0d],!1d" }, \ 920f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64RI8, kRegImm, IS_BINARY_OP | reg_def | REG_USE0 | SETS_CCODES | uses_ccodes, { REX_W, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "64RI8", "!0r,!1d" }, \ 930f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64MI8, kMemImm, mem_use | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES | uses_ccodes, { REX_W, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "64MI8", "[!0r+!1d],!2d" }, \ 940f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64AI8, kArrayImm, mem_use | IS_QUIN_OP | REG_USE01 | SETS_CCODES | uses_ccodes, { REX_W, 0, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "64AI8", "[!0r+!1r<<!2d+!3d],!4d" }, \ 950f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64TI8, kThreadImm, mem_use | IS_BINARY_OP | SETS_CCODES | uses_ccodes, { THREAD_PREFIX, REX_W, rm32_i8, 0, 0, rm32_i8_modrm, 0, 1, false }, #opname "64TI8", "fs:[!0d],!1d" } 96b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 97e296248a124ed8287b38a9225463696c18d84cd6jeffhaoENCODING_MAP(Add, IS_LOAD | IS_STORE, REG_DEF0, 0, 9896ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x00 /* RegMem8/Reg8 */, 0x01 /* RegMem32/Reg32 */, 9996ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x02 /* Reg8/RegMem8 */, 0x03 /* Reg32/RegMem32 */, 10096ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x04 /* Rax8/imm8 opcode */, 0x05 /* Rax32/imm32 */, 10196ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x80, 0x0 /* RegMem8/imm8 */, 10296ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x81, 0x0 /* RegMem32/imm32 */, 0x83, 0x0 /* RegMem32/imm8 */), 103e296248a124ed8287b38a9225463696c18d84cd6jeffhaoENCODING_MAP(Or, IS_LOAD | IS_STORE, REG_DEF0, 0, 10496ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x08 /* RegMem8/Reg8 */, 0x09 /* RegMem32/Reg32 */, 10596ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x0A /* Reg8/RegMem8 */, 0x0B /* Reg32/RegMem32 */, 10696ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x0C /* Rax8/imm8 opcode */, 0x0D /* Rax32/imm32 */, 10796ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x80, 0x1 /* RegMem8/imm8 */, 10896ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x81, 0x1 /* RegMem32/imm32 */, 0x83, 0x1 /* RegMem32/imm8 */), 109e296248a124ed8287b38a9225463696c18d84cd6jeffhaoENCODING_MAP(Adc, IS_LOAD | IS_STORE, REG_DEF0, USES_CCODES, 11096ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x10 /* RegMem8/Reg8 */, 0x11 /* RegMem32/Reg32 */, 11196ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x12 /* Reg8/RegMem8 */, 0x13 /* Reg32/RegMem32 */, 11296ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x14 /* Rax8/imm8 opcode */, 0x15 /* Rax32/imm32 */, 11396ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x80, 0x2 /* RegMem8/imm8 */, 11496ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x81, 0x2 /* RegMem32/imm32 */, 0x83, 0x2 /* RegMem32/imm8 */), 115e296248a124ed8287b38a9225463696c18d84cd6jeffhaoENCODING_MAP(Sbb, IS_LOAD | IS_STORE, REG_DEF0, USES_CCODES, 11696ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x18 /* RegMem8/Reg8 */, 0x19 /* RegMem32/Reg32 */, 11796ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x1A /* Reg8/RegMem8 */, 0x1B /* Reg32/RegMem32 */, 11896ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x1C /* Rax8/imm8 opcode */, 0x1D /* Rax32/imm32 */, 11996ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x80, 0x3 /* RegMem8/imm8 */, 12096ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x81, 0x3 /* RegMem32/imm32 */, 0x83, 0x3 /* RegMem32/imm8 */), 121e296248a124ed8287b38a9225463696c18d84cd6jeffhaoENCODING_MAP(And, IS_LOAD | IS_STORE, REG_DEF0, 0, 12296ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x20 /* RegMem8/Reg8 */, 0x21 /* RegMem32/Reg32 */, 12396ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x22 /* Reg8/RegMem8 */, 0x23 /* Reg32/RegMem32 */, 12496ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x24 /* Rax8/imm8 opcode */, 0x25 /* Rax32/imm32 */, 12596ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x80, 0x4 /* RegMem8/imm8 */, 12696ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x81, 0x4 /* RegMem32/imm32 */, 0x83, 0x4 /* RegMem32/imm8 */), 127e296248a124ed8287b38a9225463696c18d84cd6jeffhaoENCODING_MAP(Sub, IS_LOAD | IS_STORE, REG_DEF0, 0, 12896ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x28 /* RegMem8/Reg8 */, 0x29 /* RegMem32/Reg32 */, 12996ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x2A /* Reg8/RegMem8 */, 0x2B /* Reg32/RegMem32 */, 13096ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x2C /* Rax8/imm8 opcode */, 0x2D /* Rax32/imm32 */, 13196ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x80, 0x5 /* RegMem8/imm8 */, 13296ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x81, 0x5 /* RegMem32/imm32 */, 0x83, 0x5 /* RegMem32/imm8 */), 133e296248a124ed8287b38a9225463696c18d84cd6jeffhaoENCODING_MAP(Xor, IS_LOAD | IS_STORE, REG_DEF0, 0, 13496ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x30 /* RegMem8/Reg8 */, 0x31 /* RegMem32/Reg32 */, 13596ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x32 /* Reg8/RegMem8 */, 0x33 /* Reg32/RegMem32 */, 13696ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x34 /* Rax8/imm8 opcode */, 0x35 /* Rax32/imm32 */, 13796ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x80, 0x6 /* RegMem8/imm8 */, 13896ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x81, 0x6 /* RegMem32/imm32 */, 0x83, 0x6 /* RegMem32/imm8 */), 139e296248a124ed8287b38a9225463696c18d84cd6jeffhaoENCODING_MAP(Cmp, IS_LOAD, 0, 0, 14096ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x38 /* RegMem8/Reg8 */, 0x39 /* RegMem32/Reg32 */, 14196ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x3A /* Reg8/RegMem8 */, 0x3B /* Reg32/RegMem32 */, 14296ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x3C /* Rax8/imm8 opcode */, 0x3D /* Rax32/imm32 */, 14396ab420e2a78f9832a094254354062b8bc54bf72Ian Rogers 0x80, 0x7 /* RegMem8/imm8 */, 144de797834a282bf913e144f83ff044efd6d77b278Ian Rogers 0x81, 0x7 /* RegMem32/imm32 */, 0x83, 0x7 /* RegMem32/imm8 */), 145b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers#undef ENCODING_MAP 146b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 1470f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul16RRI, kRegRegImm, IS_TERTIARY_OP | REG_DEF0_USE1 | SETS_CCODES, { 0x66, 0, 0x69, 0, 0, 0, 0, 2, false }, "Imul16RRI", "!0r,!1r,!2d" }, 1480f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul16RMI, kRegMemImm, IS_LOAD | IS_QUAD_OP | REG_DEF0_USE1 | SETS_CCODES, { 0x66, 0, 0x69, 0, 0, 0, 0, 2, false }, "Imul16RMI", "!0r,[!1r+!2d],!3d" }, 1490f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul16RAI, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | REG_DEF0_USE12 | SETS_CCODES, { 0x66, 0, 0x69, 0, 0, 0, 0, 2, false }, "Imul16RAI", "!0r,[!1r+!2r<<!3d+!4d],!5d" }, 1500f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 1510f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul32RRI, kRegRegImm, IS_TERTIARY_OP | REG_DEF0_USE1 | SETS_CCODES, { 0, 0, 0x69, 0, 0, 0, 0, 4, false }, "Imul32RRI", "!0r,!1r,!2d" }, 1520f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul32RMI, kRegMemImm, IS_LOAD | IS_QUAD_OP | REG_DEF0_USE1 | SETS_CCODES, { 0, 0, 0x69, 0, 0, 0, 0, 4, false }, "Imul32RMI", "!0r,[!1r+!2d],!3d" }, 1530f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul32RAI, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | REG_DEF0_USE12 | SETS_CCODES, { 0, 0, 0x69, 0, 0, 0, 0, 4, false }, "Imul32RAI", "!0r,[!1r+!2r<<!3d+!4d],!5d" }, 1540f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul32RRI8, kRegRegImm, IS_TERTIARY_OP | REG_DEF0_USE1 | SETS_CCODES, { 0, 0, 0x6B, 0, 0, 0, 0, 1, false }, "Imul32RRI8", "!0r,!1r,!2d" }, 1550f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul32RMI8, kRegMemImm, IS_LOAD | IS_QUAD_OP | REG_DEF0_USE1 | SETS_CCODES, { 0, 0, 0x6B, 0, 0, 0, 0, 1, false }, "Imul32RMI8", "!0r,[!1r+!2d],!3d" }, 1560f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul32RAI8, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | REG_DEF0_USE12 | SETS_CCODES, { 0, 0, 0x6B, 0, 0, 0, 0, 1, false }, "Imul32RAI8", "!0r,[!1r+!2r<<!3d+!4d],!5d" }, 1570f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 1580f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul64RRI, kRegRegImm, IS_TERTIARY_OP | REG_DEF0_USE1 | SETS_CCODES, { REX_W, 0, 0x69, 0, 0, 0, 0, 4, false }, "Imul64RRI", "!0r,!1r,!2d" }, 1590f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul64RMI, kRegMemImm, IS_LOAD | IS_QUAD_OP | REG_DEF0_USE1 | SETS_CCODES, { REX_W, 0, 0x69, 0, 0, 0, 0, 4, false }, "Imul64RMI", "!0r,[!1r+!2d],!3d" }, 1600f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul64RAI, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | REG_DEF0_USE12 | SETS_CCODES, { REX_W, 0, 0x69, 0, 0, 0, 0, 4, false }, "Imul64RAI", "!0r,[!1r+!2r<<!3d+!4d],!5d" }, 1610f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul64RRI8, kRegRegImm, IS_TERTIARY_OP | REG_DEF0_USE1 | SETS_CCODES, { REX_W, 0, 0x6B, 0, 0, 0, 0, 1, false }, "Imul64RRI8", "!0r,!1r,!2d" }, 1620f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul64RMI8, kRegMemImm, IS_LOAD | IS_QUAD_OP | REG_DEF0_USE1 | SETS_CCODES, { REX_W, 0, 0x6B, 0, 0, 0, 0, 1, false }, "Imul64RMI8", "!0r,[!1r+!2d],!3d" }, 1630f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Imul64RAI8, kRegArrayImm, IS_LOAD | IS_SEXTUPLE_OP | REG_DEF0_USE12 | SETS_CCODES, { REX_W, 0, 0x6B, 0, 0, 0, 0, 1, false }, "Imul64RAI8", "!0r,[!1r+!2r<<!3d+!4d],!5d" }, 1640f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 1650f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov8MR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0, 0, 0x88, 0, 0, 0, 0, 0, true }, "Mov8MR", "[!0r+!1d],!2r" }, 1660f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov8AR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0, 0, 0x88, 0, 0, 0, 0, 0, true }, "Mov8AR", "[!0r+!1r<<!2d+!3d],!4r" }, 1670f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov8TR, kThreadReg, IS_STORE | IS_BINARY_OP | REG_USE1, { THREAD_PREFIX, 0, 0x88, 0, 0, 0, 0, 0, true }, "Mov8TR", "fs:[!0d],!1r" }, 1680f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov8RR, kRegReg, IS_BINARY_OP | REG_DEF0_USE1, { 0, 0, 0x8A, 0, 0, 0, 0, 0, true }, "Mov8RR", "!0r,!1r" }, 1690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov8RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | REG_DEF0_USE1, { 0, 0, 0x8A, 0, 0, 0, 0, 0, true }, "Mov8RM", "!0r,[!1r+!2d]" }, 1700f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov8RA, kRegArray, IS_LOAD | IS_QUIN_OP | REG_DEF0_USE12, { 0, 0, 0x8A, 0, 0, 0, 0, 0, true }, "Mov8RA", "!0r,[!1r+!2r<<!3d+!4d]" }, 1710f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov8RT, kRegThread, IS_LOAD | IS_BINARY_OP | REG_DEF0, { THREAD_PREFIX, 0, 0x8A, 0, 0, 0, 0, 0, true }, "Mov8RT", "!0r,fs:[!1d]" }, 1720f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov8RI, kMovRegImm, IS_BINARY_OP | REG_DEF0, { 0, 0, 0xB0, 0, 0, 0, 0, 1, true }, "Mov8RI", "!0r,!1d" }, 173fd0c237e7d80ad567399e760203f3cda404bf4c5Mark Mendell { kX86Mov8MI, kMemImm, IS_STORE | IS_TERTIARY_OP | REG_USE0, { 0, 0, 0xC6, 0, 0, 0, 0, 1, false}, "Mov8MI", "[!0r+!1d],!2d" }, 174fd0c237e7d80ad567399e760203f3cda404bf4c5Mark Mendell { kX86Mov8AI, kArrayImm, IS_STORE | IS_QUIN_OP | REG_USE01, { 0, 0, 0xC6, 0, 0, 0, 0, 1, false}, "Mov8AI", "[!0r+!1r<<!2d+!3d],!4d" }, 175fd0c237e7d80ad567399e760203f3cda404bf4c5Mark Mendell { kX86Mov8TI, kThreadImm, IS_STORE | IS_BINARY_OP, { THREAD_PREFIX, 0, 0xC6, 0, 0, 0, 0, 1, false}, "Mov8TI", "fs:[!0d],!1d" }, 1760f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 1770f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16MR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0x66, 0, 0x89, 0, 0, 0, 0, 0, false }, "Mov16MR", "[!0r+!1d],!2r" }, 1780f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16AR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0x66, 0, 0x89, 0, 0, 0, 0, 0, false }, "Mov16AR", "[!0r+!1r<<!2d+!3d],!4r" }, 1790f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16TR, kThreadReg, IS_STORE | IS_BINARY_OP | REG_USE1, { THREAD_PREFIX, 0x66, 0x89, 0, 0, 0, 0, 0, false }, "Mov16TR", "fs:[!0d],!1r" }, 1800f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16RR, kRegReg, IS_BINARY_OP | REG_DEF0_USE1, { 0x66, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov16RR", "!0r,!1r" }, 1810f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | REG_DEF0_USE1, { 0x66, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov16RM", "!0r,[!1r+!2d]" }, 1820f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16RA, kRegArray, IS_LOAD | IS_QUIN_OP | REG_DEF0_USE12, { 0x66, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov16RA", "!0r,[!1r+!2r<<!3d+!4d]" }, 1830f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16RT, kRegThread, IS_LOAD | IS_BINARY_OP | REG_DEF0, { THREAD_PREFIX, 0x66, 0x8B, 0, 0, 0, 0, 0, false }, "Mov16RT", "!0r,fs:[!1d]" }, 1840f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16RI, kMovRegImm, IS_BINARY_OP | REG_DEF0, { 0x66, 0, 0xB8, 0, 0, 0, 0, 2, false }, "Mov16RI", "!0r,!1d" }, 1850f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16MI, kMemImm, IS_STORE | IS_TERTIARY_OP | REG_USE0, { 0x66, 0, 0xC7, 0, 0, 0, 0, 2, false }, "Mov16MI", "[!0r+!1d],!2d" }, 1860f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16AI, kArrayImm, IS_STORE | IS_QUIN_OP | REG_USE01, { 0x66, 0, 0xC7, 0, 0, 0, 0, 2, false }, "Mov16AI", "[!0r+!1r<<!2d+!3d],!4d" }, 1870f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov16TI, kThreadImm, IS_STORE | IS_BINARY_OP, { THREAD_PREFIX, 0x66, 0xC7, 0, 0, 0, 0, 2, false }, "Mov16TI", "fs:[!0d],!1d" }, 1880f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 1890f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32MR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0, 0, 0x89, 0, 0, 0, 0, 0, false }, "Mov32MR", "[!0r+!1d],!2r" }, 1900f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32AR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0, 0, 0x89, 0, 0, 0, 0, 0, false }, "Mov32AR", "[!0r+!1r<<!2d+!3d],!4r" }, 1910f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32TR, kThreadReg, IS_STORE | IS_BINARY_OP | REG_USE1, { THREAD_PREFIX, 0, 0x89, 0, 0, 0, 0, 0, false }, "Mov32TR", "fs:[!0d],!1r" }, 1920f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32RR, kRegReg, IS_BINARY_OP | REG_DEF0_USE1, { 0, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov32RR", "!0r,!1r" }, 1930f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | REG_DEF0_USE1, { 0, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov32RM", "!0r,[!1r+!2d]" }, 1940f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32RA, kRegArray, IS_LOAD | IS_QUIN_OP | REG_DEF0_USE12, { 0, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov32RA", "!0r,[!1r+!2r<<!3d+!4d]" }, 1950f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32RT, kRegThread, IS_LOAD | IS_BINARY_OP | REG_DEF0, { THREAD_PREFIX, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov32RT", "!0r,fs:[!1d]" }, 1960f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32RI, kMovRegImm, IS_BINARY_OP | REG_DEF0, { 0, 0, 0xB8, 0, 0, 0, 0, 4, false }, "Mov32RI", "!0r,!1d" }, 1970f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32MI, kMemImm, IS_STORE | IS_TERTIARY_OP | REG_USE0, { 0, 0, 0xC7, 0, 0, 0, 0, 4, false }, "Mov32MI", "[!0r+!1d],!2d" }, 1980f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32AI, kArrayImm, IS_STORE | IS_QUIN_OP | REG_USE01, { 0, 0, 0xC7, 0, 0, 0, 0, 4, false }, "Mov32AI", "[!0r+!1r<<!2d+!3d],!4d" }, 1990f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov32TI, kThreadImm, IS_STORE | IS_BINARY_OP, { THREAD_PREFIX, 0, 0xC7, 0, 0, 0, 0, 4, false }, "Mov32TI", "fs:[!0d],!1d" }, 2000f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 2010f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Lea32RM, kRegMem, IS_TERTIARY_OP | IS_LOAD | REG_DEF0_USE1, { 0, 0, 0x8D, 0, 0, 0, 0, 0, false }, "Lea32RM", "!0r,[!1r+!2d]" }, 2020f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Lea32RA, kRegArray, IS_QUIN_OP | REG_DEF0_USE12, { 0, 0, 0x8D, 0, 0, 0, 0, 0, false }, "Lea32RA", "!0r,[!1r+!2r<<!3d+!4d]" }, 2030f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 2040f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64MR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { REX_W, 0, 0x89, 0, 0, 0, 0, 0, false }, "Mov64MR", "[!0r+!1d],!2r" }, 2050f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64AR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { REX_W, 0, 0x89, 0, 0, 0, 0, 0, false }, "Mov64AR", "[!0r+!1r<<!2d+!3d],!4r" }, 2060f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64TR, kThreadReg, IS_STORE | IS_BINARY_OP | REG_USE1, { THREAD_PREFIX, REX_W, 0x89, 0, 0, 0, 0, 0, false }, "Mov64TR", "fs:[!0d],!1r" }, 2070f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64RR, kRegReg, IS_BINARY_OP | REG_DEF0_USE1, { REX_W, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov64RR", "!0r,!1r" }, 2080f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | REG_DEF0_USE1, { REX_W, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov64RM", "!0r,[!1r+!2d]" }, 2090f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64RA, kRegArray, IS_LOAD | IS_QUIN_OP | REG_DEF0_USE12, { REX_W, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov64RA", "!0r,[!1r+!2r<<!3d+!4d]" }, 2100f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64RT, kRegThread, IS_LOAD | IS_BINARY_OP | REG_DEF0, { THREAD_PREFIX, REX_W, 0x8B, 0, 0, 0, 0, 0, false }, "Mov64RT", "!0r,fs:[!1d]" }, 2115192cbb12856b12620dc346758605baaa1469cedYixin Shou { kX86Mov64RI32, kRegImm, IS_BINARY_OP | REG_DEF0, { REX_W, 0, 0xC7, 0, 0, 0, 0, 4, false }, "Mov64RI32", "!0r,!1d" }, 2125192cbb12856b12620dc346758605baaa1469cedYixin Shou { kX86Mov64RI64, kMovRegQuadImm, IS_TERTIARY_OP | REG_DEF0, { REX_W, 0, 0xB8, 0, 0, 0, 0, 8, false }, "Mov64RI64", "!0r,!1q" }, 2130f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64MI, kMemImm, IS_STORE | IS_TERTIARY_OP | REG_USE0, { REX_W, 0, 0xC7, 0, 0, 0, 0, 4, false }, "Mov64MI", "[!0r+!1d],!2d" }, 2140f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64AI, kArrayImm, IS_STORE | IS_QUIN_OP | REG_USE01, { REX_W, 0, 0xC7, 0, 0, 0, 0, 4, false }, "Mov64AI", "[!0r+!1r<<!2d+!3d],!4d" }, 2150f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mov64TI, kThreadImm, IS_STORE | IS_BINARY_OP, { THREAD_PREFIX, REX_W, 0xC7, 0, 0, 0, 0, 4, false }, "Mov64TI", "fs:[!0d],!1d" }, 2160f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 2170f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Lea64RM, kRegMem, IS_TERTIARY_OP | IS_LOAD | REG_DEF0_USE1, { REX_W, 0, 0x8D, 0, 0, 0, 0, 0, false }, "Lea64RM", "!0r,[!1r+!2d]" }, 2180f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Lea64RA, kRegArray, IS_QUIN_OP | REG_DEF0_USE12, { REX_W, 0, 0x8D, 0, 0, 0, 0, 0, false }, "Lea64RA", "!0r,[!1r+!2r<<!3d+!4d]" }, 2190f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 2200f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Cmov32RRC, kRegRegCond, IS_TERTIARY_OP | REG_DEF0_USE01 | USES_CCODES, { 0, 0, 0x0F, 0x40, 0, 0, 0, 0, false }, "Cmovcc32RR", "!2c !0r,!1r" }, 2210f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Cmov64RRC, kRegRegCond, IS_TERTIARY_OP | REG_DEF0_USE01 | USES_CCODES, { REX_W, 0, 0x0F, 0x40, 0, 0, 0, 0, false }, "Cmovcc64RR", "!2c !0r,!1r" }, 2220f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 2230f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Cmov32RMC, kRegMemCond, IS_QUAD_OP | IS_LOAD | REG_DEF0_USE01 | USES_CCODES, { 0, 0, 0x0F, 0x40, 0, 0, 0, 0, false }, "Cmovcc32RM", "!3c !0r,[!1r+!2d]" }, 2240f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Cmov64RMC, kRegMemCond, IS_QUAD_OP | IS_LOAD | REG_DEF0_USE01 | USES_CCODES, { REX_W, 0, 0x0F, 0x40, 0, 0, 0, 0, false }, "Cmovcc64RM", "!3c !0r,[!1r+!2d]" }, 2252637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell 226b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers#define SHIFT_ENCODING_MAP(opname, modrm_opcode) \ 2270f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8RI, kShiftRegImm, IS_BINARY_OP | REG_DEF0_USE0 | SETS_CCODES, { 0, 0, 0xC0, 0, 0, modrm_opcode, 0xD1, 1, true }, #opname "8RI", "!0r,!1d" }, \ 2280f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8MI, kShiftMemImm, IS_LOAD | IS_STORE | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES, { 0, 0, 0xC0, 0, 0, modrm_opcode, 0xD1, 1, true }, #opname "8MI", "[!0r+!1d],!2d" }, \ 2290f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8AI, kShiftArrayImm, IS_LOAD | IS_STORE | IS_QUIN_OP | REG_USE01 | SETS_CCODES, { 0, 0, 0xC0, 0, 0, modrm_opcode, 0xD1, 1, true }, #opname "8AI", "[!0r+!1r<<!2d+!3d],!4d" }, \ 2300f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8RC, kShiftRegCl, IS_BINARY_OP | REG_DEF0_USE0 | REG_USEC | SETS_CCODES, { 0, 0, 0xD2, 0, 0, modrm_opcode, 0, 1, true }, #opname "8RC", "!0r,cl" }, \ 2310f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8MC, kShiftMemCl, IS_LOAD | IS_STORE | IS_TERTIARY_OP | REG_USE0 | REG_USEC | SETS_CCODES, { 0, 0, 0xD2, 0, 0, modrm_opcode, 0, 1, true }, #opname "8MC", "[!0r+!1d],cl" }, \ 2320f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8AC, kShiftArrayCl, IS_LOAD | IS_STORE | IS_QUIN_OP | REG_USE01 | REG_USEC | SETS_CCODES, { 0, 0, 0xD2, 0, 0, modrm_opcode, 0, 1, true }, #opname "8AC", "[!0r+!1r<<!2d+!3d],cl" }, \ 233b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers \ 2340f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16RI, kShiftRegImm, IS_BINARY_OP | REG_DEF0_USE0 | SETS_CCODES, { 0x66, 0, 0xC1, 0, 0, modrm_opcode, 0xD1, 1, false }, #opname "16RI", "!0r,!1d" }, \ 2350f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16MI, kShiftMemImm, IS_LOAD | IS_STORE | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES, { 0x66, 0, 0xC1, 0, 0, modrm_opcode, 0xD1, 1, false }, #opname "16MI", "[!0r+!1d],!2d" }, \ 2360f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16AI, kShiftArrayImm, IS_LOAD | IS_STORE | IS_QUIN_OP | REG_USE01 | SETS_CCODES, { 0x66, 0, 0xC1, 0, 0, modrm_opcode, 0xD1, 1, false }, #opname "16AI", "[!0r+!1r<<!2d+!3d],!4d" }, \ 2370f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16RC, kShiftRegCl, IS_BINARY_OP | REG_DEF0_USE0 | REG_USEC | SETS_CCODES, { 0x66, 0, 0xD3, 0, 0, modrm_opcode, 0, 1, false }, #opname "16RC", "!0r,cl" }, \ 2380f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16MC, kShiftMemCl, IS_LOAD | IS_STORE | IS_TERTIARY_OP | REG_USE0 | REG_USEC | SETS_CCODES, { 0x66, 0, 0xD3, 0, 0, modrm_opcode, 0, 1, false }, #opname "16MC", "[!0r+!1d],cl" }, \ 2390f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16AC, kShiftArrayCl, IS_LOAD | IS_STORE | IS_QUIN_OP | REG_USE01 | REG_USEC | SETS_CCODES, { 0x66, 0, 0xD3, 0, 0, modrm_opcode, 0, 1, false }, #opname "16AC", "[!0r+!1r<<!2d+!3d],cl" }, \ 240b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers \ 2410f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32RI, kShiftRegImm, IS_BINARY_OP | REG_DEF0_USE0 | SETS_CCODES, { 0, 0, 0xC1, 0, 0, modrm_opcode, 0xD1, 1, false }, #opname "32RI", "!0r,!1d" }, \ 2420f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32MI, kShiftMemImm, IS_LOAD | IS_STORE | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES, { 0, 0, 0xC1, 0, 0, modrm_opcode, 0xD1, 1, false }, #opname "32MI", "[!0r+!1d],!2d" }, \ 2430f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32AI, kShiftArrayImm, IS_LOAD | IS_STORE | IS_QUIN_OP | REG_USE01 | SETS_CCODES, { 0, 0, 0xC1, 0, 0, modrm_opcode, 0xD1, 1, false }, #opname "32AI", "[!0r+!1r<<!2d+!3d],!4d" }, \ 2440f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32RC, kShiftRegCl, IS_BINARY_OP | REG_DEF0_USE0 | REG_USEC | SETS_CCODES, { 0, 0, 0xD3, 0, 0, modrm_opcode, 0, 0, false }, #opname "32RC", "!0r,cl" }, \ 2450f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32MC, kShiftMemCl, IS_LOAD | IS_STORE | IS_TERTIARY_OP | REG_USE0 | REG_USEC | SETS_CCODES, { 0, 0, 0xD3, 0, 0, modrm_opcode, 0, 0, false }, #opname "32MC", "[!0r+!1d],cl" }, \ 2460f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32AC, kShiftArrayCl, IS_LOAD | IS_STORE | IS_QUIN_OP | REG_USE01 | REG_USEC | SETS_CCODES, { 0, 0, 0xD3, 0, 0, modrm_opcode, 0, 0, false }, #opname "32AC", "[!0r+!1r<<!2d+!3d],cl" }, \ 24796992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko \ 2480f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64RI, kShiftRegImm, IS_BINARY_OP | REG_DEF0_USE0 | SETS_CCODES, { REX_W, 0, 0xC1, 0, 0, modrm_opcode, 0xD1, 1, false }, #opname "64RI", "!0r,!1d" }, \ 2490f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64MI, kShiftMemImm, IS_LOAD | IS_STORE | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES, { REX_W, 0, 0xC1, 0, 0, modrm_opcode, 0xD1, 1, false }, #opname "64MI", "[!0r+!1d],!2d" }, \ 2500f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64AI, kShiftArrayImm, IS_LOAD | IS_STORE | IS_QUIN_OP | REG_USE01 | SETS_CCODES, { REX_W, 0, 0xC1, 0, 0, modrm_opcode, 0xD1, 1, false }, #opname "64AI", "[!0r+!1r<<!2d+!3d],!4d" }, \ 2510f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64RC, kShiftRegCl, IS_BINARY_OP | REG_DEF0_USE0 | REG_USEC | SETS_CCODES, { REX_W, 0, 0xD3, 0, 0, modrm_opcode, 0, 0, false }, #opname "64RC", "!0r,cl" }, \ 2520f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64MC, kShiftMemCl, IS_LOAD | IS_STORE | IS_TERTIARY_OP | REG_USE0 | REG_USEC | SETS_CCODES, { REX_W, 0, 0xD3, 0, 0, modrm_opcode, 0, 0, false }, #opname "64MC", "[!0r+!1d],cl" }, \ 2530f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64AC, kShiftArrayCl, IS_LOAD | IS_STORE | IS_QUIN_OP | REG_USE01 | REG_USEC | SETS_CCODES, { REX_W, 0, 0xD3, 0, 0, modrm_opcode, 0, 0, false }, #opname "64AC", "[!0r+!1r<<!2d+!3d],cl" } 254b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 255b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers SHIFT_ENCODING_MAP(Rol, 0x0), 256b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers SHIFT_ENCODING_MAP(Ror, 0x1), 257b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers SHIFT_ENCODING_MAP(Rcl, 0x2), 258b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers SHIFT_ENCODING_MAP(Rcr, 0x3), 259b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers SHIFT_ENCODING_MAP(Sal, 0x4), 2607caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers SHIFT_ENCODING_MAP(Shr, 0x5), 261b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers SHIFT_ENCODING_MAP(Sar, 0x7), 262b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers#undef SHIFT_ENCODING_MAP 263b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 2640f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Cmc, kNullary, NO_OPERAND, { 0, 0, 0xF5, 0, 0, 0, 0, 0, false }, "Cmc", "" }, 2650f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Shld32RRI, kRegRegImmStore, IS_TERTIARY_OP | REG_DEF0_USE01 | SETS_CCODES, { 0, 0, 0x0F, 0xA4, 0, 0, 0, 1, false }, "Shld32RRI", "!0r,!1r,!2d" }, 2660f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Shld32MRI, kMemRegImm, IS_QUAD_OP | REG_USE02 | IS_LOAD | IS_STORE | SETS_CCODES, { 0, 0, 0x0F, 0xA4, 0, 0, 0, 1, false }, "Shld32MRI", "[!0r+!1d],!2r,!3d" }, 2670f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Shrd32RRI, kRegRegImmStore, IS_TERTIARY_OP | REG_DEF0_USE01 | SETS_CCODES, { 0, 0, 0x0F, 0xAC, 0, 0, 0, 1, false }, "Shrd32RRI", "!0r,!1r,!2d" }, 2680f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Shrd32MRI, kMemRegImm, IS_QUAD_OP | REG_USE02 | IS_LOAD | IS_STORE | SETS_CCODES, { 0, 0, 0x0F, 0xAC, 0, 0, 0, 1, false }, "Shrd32MRI", "[!0r+!1d],!2r,!3d" }, 2690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Shld64RRI, kRegRegImmStore, IS_TERTIARY_OP | REG_DEF0_USE01 | SETS_CCODES, { REX_W, 0, 0x0F, 0xA4, 0, 0, 0, 1, false }, "Shld64RRI", "!0r,!1r,!2d" }, 2700f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Shld64MRI, kMemRegImm, IS_QUAD_OP | REG_USE02 | IS_LOAD | IS_STORE | SETS_CCODES, { REX_W, 0, 0x0F, 0xA4, 0, 0, 0, 1, false }, "Shld64MRI", "[!0r+!1d],!2r,!3d" }, 2710f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Shrd64RRI, kRegRegImmStore, IS_TERTIARY_OP | REG_DEF0_USE01 | SETS_CCODES, { REX_W, 0, 0x0F, 0xAC, 0, 0, 0, 1, false }, "Shrd64RRI", "!0r,!1r,!2d" }, 2720f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Shrd64MRI, kMemRegImm, IS_QUAD_OP | REG_USE02 | IS_LOAD | IS_STORE | SETS_CCODES, { REX_W, 0, 0x0F, 0xAC, 0, 0, 0, 1, false }, "Shrd64MRI", "[!0r+!1d],!2r,!3d" }, 2730f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 27469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test8RI, kRegImm, IS_BINARY_OP | REG_USE0 | SETS_CCODES, { 0, 0, 0xF6, 0, 0, 0, 0, 1, true }, "Test8RI", "!0r,!1d" }, 27569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test8MI, kMemImm, IS_LOAD | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES, { 0, 0, 0xF6, 0, 0, 0, 0, 1, true }, "Test8MI", "[!0r+!1d],!2d" }, 27669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test8AI, kArrayImm, IS_LOAD | IS_QUIN_OP | REG_USE01 | SETS_CCODES, { 0, 0, 0xF6, 0, 0, 0, 0, 1, true }, "Test8AI", "[!0r+!1r<<!2d+!3d],!4d" }, 27769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test16RI, kRegImm, IS_BINARY_OP | REG_USE0 | SETS_CCODES, { 0x66, 0, 0xF7, 0, 0, 0, 0, 2, false }, "Test16RI", "!0r,!1d" }, 27869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test16MI, kMemImm, IS_LOAD | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES, { 0x66, 0, 0xF7, 0, 0, 0, 0, 2, false }, "Test16MI", "[!0r+!1d],!2d" }, 27969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test16AI, kArrayImm, IS_LOAD | IS_QUIN_OP | REG_USE01 | SETS_CCODES, { 0x66, 0, 0xF7, 0, 0, 0, 0, 2, false }, "Test16AI", "[!0r+!1r<<!2d+!3d],!4d" }, 28069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test32RI, kRegImm, IS_BINARY_OP | REG_USE0 | SETS_CCODES, { 0, 0, 0xF7, 0, 0, 0, 0, 4, false }, "Test32RI", "!0r,!1d" }, 28169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test32MI, kMemImm, IS_LOAD | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES, { 0, 0, 0xF7, 0, 0, 0, 0, 4, false }, "Test32MI", "[!0r+!1d],!2d" }, 28269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test32AI, kArrayImm, IS_LOAD | IS_QUIN_OP | REG_USE01 | SETS_CCODES, { 0, 0, 0xF7, 0, 0, 0, 0, 4, false }, "Test32AI", "[!0r+!1r<<!2d+!3d],!4d" }, 2830f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Test64RI, kRegImm, IS_BINARY_OP | REG_USE0 | SETS_CCODES, { REX_W, 0, 0xF7, 0, 0, 0, 0, 4, false }, "Test64RI", "!0r,!1d" }, 2840f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Test64MI, kMemImm, IS_LOAD | IS_TERTIARY_OP | REG_USE0 | SETS_CCODES, { REX_W, 0, 0xF7, 0, 0, 0, 0, 4, false }, "Test64MI", "[!0r+!1d],!2d" }, 2850f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Test64AI, kArrayImm, IS_LOAD | IS_QUIN_OP | REG_USE01 | SETS_CCODES, { REX_W, 0, 0xF7, 0, 0, 0, 0, 4, false }, "Test64AI", "[!0r+!1r<<!2d+!3d],!4d" }, 2860f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 28769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison { kX86Test32RR, kRegReg, IS_BINARY_OP | REG_USE01 | SETS_CCODES, { 0, 0, 0x85, 0, 0, 0, 0, 0, false }, "Test32RR", "!0r,!1r" }, 2880f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Test64RR, kRegReg, IS_BINARY_OP | REG_USE01 | SETS_CCODES, { REX_W, 0, 0x85, 0, 0, 0, 0, 0, false }, "Test64RR", "!0r,!1r" }, 289cf8184164650d7686b9f685850463f5976bc3251Chao-ying Fu { kX86Test32RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | REG_USE01 | SETS_CCODES, { 0, 0, 0x85, 0, 0, 0, 0, 0, false }, "Test32RM", "!0r,[!1r+!2d]" }, 290e296248a124ed8287b38a9225463696c18d84cd6jeffhao 291e296248a124ed8287b38a9225463696c18d84cd6jeffhao#define UNARY_ENCODING_MAP(opname, modrm, is_store, sets_ccodes, \ 292b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers reg, reg_kind, reg_flags, \ 293b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers mem, mem_kind, mem_flags, \ 294e296248a124ed8287b38a9225463696c18d84cd6jeffhao arr, arr_kind, arr_flags, imm, \ 295e296248a124ed8287b38a9225463696c18d84cd6jeffhao b_flags, hw_flags, w_flags, \ 296e296248a124ed8287b38a9225463696c18d84cd6jeffhao b_format, hw_format, w_format) \ 2970f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8 ## reg, reg_kind, reg_flags | b_flags | sets_ccodes, { 0, 0, 0xF6, 0, 0, modrm, 0, imm << 0, true }, #opname "8" #reg, b_format "!0r" }, \ 2980f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8 ## mem, mem_kind, IS_LOAD | is_store | mem_flags | b_flags | sets_ccodes, { 0, 0, 0xF6, 0, 0, modrm, 0, imm << 0, true }, #opname "8" #mem, b_format "[!0r+!1d]" }, \ 2990f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 8 ## arr, arr_kind, IS_LOAD | is_store | arr_flags | b_flags | sets_ccodes, { 0, 0, 0xF6, 0, 0, modrm, 0, imm << 0, true }, #opname "8" #arr, b_format "[!0r+!1r<<!2d+!3d]" }, \ 3000f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16 ## reg, reg_kind, reg_flags | hw_flags | sets_ccodes, { 0x66, 0, 0xF7, 0, 0, modrm, 0, imm << 1, false }, #opname "16" #reg, hw_format "!0r" }, \ 3010f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16 ## mem, mem_kind, IS_LOAD | is_store | mem_flags | hw_flags | sets_ccodes, { 0x66, 0, 0xF7, 0, 0, modrm, 0, imm << 1, false }, #opname "16" #mem, hw_format "[!0r+!1d]" }, \ 3020f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 16 ## arr, arr_kind, IS_LOAD | is_store | arr_flags | hw_flags | sets_ccodes, { 0x66, 0, 0xF7, 0, 0, modrm, 0, imm << 1, false }, #opname "16" #arr, hw_format "[!0r+!1r<<!2d+!3d]" }, \ 3030f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32 ## reg, reg_kind, reg_flags | w_flags | sets_ccodes, { 0, 0, 0xF7, 0, 0, modrm, 0, imm << 2, false }, #opname "32" #reg, w_format "!0r" }, \ 3040f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32 ## mem, mem_kind, IS_LOAD | is_store | mem_flags | w_flags | sets_ccodes, { 0, 0, 0xF7, 0, 0, modrm, 0, imm << 2, false }, #opname "32" #mem, w_format "[!0r+!1d]" }, \ 3050f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 32 ## arr, arr_kind, IS_LOAD | is_store | arr_flags | w_flags | sets_ccodes, { 0, 0, 0xF7, 0, 0, modrm, 0, imm << 2, false }, #opname "32" #arr, w_format "[!0r+!1r<<!2d+!3d]" }, \ 3060f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64 ## reg, reg_kind, reg_flags | w_flags | sets_ccodes, { REX_W, 0, 0xF7, 0, 0, modrm, 0, imm << 2, false }, #opname "64" #reg, w_format "!0r" }, \ 3070f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64 ## mem, mem_kind, IS_LOAD | is_store | mem_flags | w_flags | sets_ccodes, { REX_W, 0, 0xF7, 0, 0, modrm, 0, imm << 2, false }, #opname "64" #mem, w_format "[!0r+!1d]" }, \ 3080f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## 64 ## arr, arr_kind, IS_LOAD | is_store | arr_flags | w_flags | sets_ccodes, { REX_W, 0, 0xF7, 0, 0, modrm, 0, imm << 2, false }, #opname "64" #arr, w_format "[!0r+!1r<<!2d+!3d]" } 309e296248a124ed8287b38a9225463696c18d84cd6jeffhao 310e296248a124ed8287b38a9225463696c18d84cd6jeffhao UNARY_ENCODING_MAP(Not, 0x2, IS_STORE, 0, R, kReg, IS_UNARY_OP | REG_DEF0_USE0, M, kMem, IS_BINARY_OP | REG_USE0, A, kArray, IS_QUAD_OP | REG_USE01, 0, 0, 0, 0, "", "", ""), 311e296248a124ed8287b38a9225463696c18d84cd6jeffhao UNARY_ENCODING_MAP(Neg, 0x3, IS_STORE, SETS_CCODES, R, kReg, IS_UNARY_OP | REG_DEF0_USE0, M, kMem, IS_BINARY_OP | REG_USE0, A, kArray, IS_QUAD_OP | REG_USE01, 0, 0, 0, 0, "", "", ""), 312b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 3132bf31e67694da24a19fc1f328285cebb1a4b9964Mark Mendell UNARY_ENCODING_MAP(Mul, 0x4, 0, SETS_CCODES, DaR, kReg, IS_UNARY_OP | REG_USE0, DaM, kMem, IS_BINARY_OP | REG_USE0, DaA, kArray, IS_QUAD_OP | REG_USE01, 0, REG_DEFA_USEA, REG_DEFAD_USEA, REG_DEFAD_USEA, "ax,al,", "dx:ax,ax,", "edx:eax,eax,"), 3142bf31e67694da24a19fc1f328285cebb1a4b9964Mark Mendell UNARY_ENCODING_MAP(Imul, 0x5, 0, SETS_CCODES, DaR, kReg, IS_UNARY_OP | REG_USE0, DaM, kMem, IS_BINARY_OP | REG_USE0, DaA, kArray, IS_QUAD_OP | REG_USE01, 0, REG_DEFA_USEA, REG_DEFAD_USEA, REG_DEFAD_USEA, "ax,al,", "dx:ax,ax,", "edx:eax,eax,"), 3152bf31e67694da24a19fc1f328285cebb1a4b9964Mark Mendell UNARY_ENCODING_MAP(Divmod, 0x6, 0, SETS_CCODES, DaR, kReg, IS_UNARY_OP | REG_USE0, DaM, kMem, IS_BINARY_OP | REG_USE0, DaA, kArray, IS_QUAD_OP | REG_USE01, 0, REG_DEFA_USEA, REG_DEFAD_USEAD, REG_DEFAD_USEAD, "ah:al,ax,", "dx:ax,dx:ax,", "edx:eax,edx:eax,"), 3162bf31e67694da24a19fc1f328285cebb1a4b9964Mark Mendell UNARY_ENCODING_MAP(Idivmod, 0x7, 0, SETS_CCODES, DaR, kReg, IS_UNARY_OP | REG_USE0, DaM, kMem, IS_BINARY_OP | REG_USE0, DaA, kArray, IS_QUAD_OP | REG_USE01, 0, REG_DEFA_USEA, REG_DEFAD_USEAD, REG_DEFAD_USEAD, "ah:al,ax,", "dx:ax,dx:ax,", "edx:eax,edx:eax,"), 317b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers#undef UNARY_ENCODING_MAP 318b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 3190f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kx86Cdq32Da, kRegOpcode, NO_OPERAND | REG_DEFAD_USEA, { 0, 0, 0x99, 0, 0, 0, 0, 0, false }, "Cdq", "" }, 3200f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kx86Cqo64Da, kRegOpcode, NO_OPERAND | REG_DEFAD_USEA, { REX_W, 0, 0x99, 0, 0, 0, 0, 0, false }, "Cqo", "" }, 3210f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Bswap32R, kRegOpcode, IS_UNARY_OP | REG_DEF0_USE0, { 0, 0, 0x0F, 0xC8, 0, 0, 0, 0, false }, "Bswap32R", "!0r" }, 322c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk { kX86Bswap64R, kRegOpcode, IS_UNARY_OP | REG_DEF0_USE0, { REX_W, 0, 0x0F, 0xC8, 0, 0, 0, 0, false }, "Bswap64R", "!0r" }, 3230f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Push32R, kRegOpcode, IS_UNARY_OP | REG_USE0 | REG_USE_SP | REG_DEF_SP | IS_STORE, { 0, 0, 0x50, 0, 0, 0, 0, 0, false }, "Push32R", "!0r" }, 3240f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Pop32R, kRegOpcode, IS_UNARY_OP | REG_DEF0 | REG_USE_SP | REG_DEF_SP | IS_LOAD, { 0, 0, 0x58, 0, 0, 0, 0, 0, false }, "Pop32R", "!0r" }, 325a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko 326e296248a124ed8287b38a9225463696c18d84cd6jeffhao#define EXT_0F_ENCODING_MAP(opname, prefix, opcode, reg_def) \ 3270f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## RR, kRegReg, IS_BINARY_OP | reg_def | REG_USE1, { prefix, 0, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RR", "!0r,!1r" }, \ 3280f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE1, { prefix, 0, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RM", "!0r,[!1r+!2d]" }, \ 3290f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## RA, kRegArray, IS_LOAD | IS_QUIN_OP | reg_def | REG_USE12, { prefix, 0, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RA", "!0r,[!1r+!2r<<!3d+!4d]" } 330b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 331021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu// This is a special encoding with r8_form on the second register only 332021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu// for Movzx8 and Movsx8. 333021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu#define EXT_0F_R8_FORM_ENCODING_MAP(opname, prefix, opcode, reg_def) \ 334021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu{ kX86 ## opname ## RR, kRegReg, IS_BINARY_OP | reg_def | REG_USE1, { prefix, 0, 0x0F, opcode, 0, 0, 0, 0, true }, #opname "RR", "!0r,!1r" }, \ 335021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu{ kX86 ## opname ## RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE1, { prefix, 0, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RM", "!0r,[!1r+!2d]" }, \ 336021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu{ kX86 ## opname ## RA, kRegArray, IS_LOAD | IS_QUIN_OP | reg_def | REG_USE12, { prefix, 0, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RA", "!0r,[!1r+!2r<<!3d+!4d]" } 337021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu 338e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu#define EXT_0F_REX_W_ENCODING_MAP(opname, prefix, opcode, reg_def) \ 3390f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## RR, kRegReg, IS_BINARY_OP | reg_def | REG_USE1, { prefix, REX_W, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RR", "!0r,!1r" }, \ 3400f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE1, { prefix, REX_W, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RM", "!0r,[!1r+!2d]" }, \ 3410f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## RA, kRegArray, IS_LOAD | IS_QUIN_OP | reg_def | REG_USE12, { prefix, REX_W, 0x0F, opcode, 0, 0, 0, 0, false }, #opname "RA", "!0r,[!1r+!2r<<!3d+!4d]" } 342e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 343fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell#define EXT_0F_ENCODING2_MAP(opname, prefix, opcode, opcode2, reg_def) \ 3440f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## RR, kRegReg, IS_BINARY_OP | reg_def | REG_USE1, { prefix, 0, 0x0F, opcode, opcode2, 0, 0, 0, false }, #opname "RR", "!0r,!1r" }, \ 3450f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | reg_def | REG_USE1, { prefix, 0, 0x0F, opcode, opcode2, 0, 0, 0, false }, #opname "RM", "!0r,[!1r+!2d]" }, \ 3460f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers{ kX86 ## opname ## RA, kRegArray, IS_LOAD | IS_QUIN_OP | reg_def | REG_USE12, { prefix, 0, 0x0F, opcode, opcode2, 0, 0, 0, false }, #opname "RA", "!0r,[!1r+!2r<<!3d+!4d]" } 347fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell 348e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Movsd, 0xF2, 0x10, REG_DEF0), 3490f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovsdMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0xF2, 0, 0x0F, 0x11, 0, 0, 0, 0, false }, "MovsdMR", "[!0r+!1d],!2r" }, 3500f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovsdAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0xF2, 0, 0x0F, 0x11, 0, 0, 0, 0, false }, "MovsdAR", "[!0r+!1r<<!2d+!3d],!4r" }, 351b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 352e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Movss, 0xF3, 0x10, REG_DEF0), 3530f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovssMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0xF3, 0, 0x0F, 0x11, 0, 0, 0, 0, false }, "MovssMR", "[!0r+!1d],!2r" }, 3540f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovssAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0xF3, 0, 0x0F, 0x11, 0, 0, 0, 0, false }, "MovssAR", "[!0r+!1r<<!2d+!3d],!4r" }, 355b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 356e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Cvtsi2sd, 0xF2, 0x2A, REG_DEF0), 357e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Cvtsi2ss, 0xF3, 0x2A, REG_DEF0), 358e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu EXT_0F_REX_W_ENCODING_MAP(Cvtsqi2sd, 0xF2, 0x2A, REG_DEF0), 359e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu EXT_0F_REX_W_ENCODING_MAP(Cvtsqi2ss, 0xF3, 0x2A, REG_DEF0), 360e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Cvttsd2si, 0xF2, 0x2C, REG_DEF0), 361e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Cvttss2si, 0xF3, 0x2C, REG_DEF0), 362e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu EXT_0F_REX_W_ENCODING_MAP(Cvttsd2sqi, 0xF2, 0x2C, REG_DEF0), 363e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu EXT_0F_REX_W_ENCODING_MAP(Cvttss2sqi, 0xF3, 0x2C, REG_DEF0), 364e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Cvtsd2si, 0xF2, 0x2D, REG_DEF0), 365e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Cvtss2si, 0xF3, 0x2D, REG_DEF0), 3662637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Ucomisd, 0x66, 0x2E, SETS_CCODES|REG_USE0), 3672637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Ucomiss, 0x00, 0x2E, SETS_CCODES|REG_USE0), 3682637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Comisd, 0x66, 0x2F, SETS_CCODES|REG_USE0), 3692637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Comiss, 0x00, 0x2F, SETS_CCODES|REG_USE0), 3701222c96fafe98061cfc57d3bd115f46edb64e624Alexei Zavjalov EXT_0F_ENCODING_MAP(Orpd, 0x66, 0x56, REG_DEF0_USE0), 3712637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Orps, 0x00, 0x56, REG_DEF0_USE0), 3721222c96fafe98061cfc57d3bd115f46edb64e624Alexei Zavjalov EXT_0F_ENCODING_MAP(Andpd, 0x66, 0x54, REG_DEF0_USE0), 3731222c96fafe98061cfc57d3bd115f46edb64e624Alexei Zavjalov EXT_0F_ENCODING_MAP(Andps, 0x00, 0x54, REG_DEF0_USE0), 3741222c96fafe98061cfc57d3bd115f46edb64e624Alexei Zavjalov EXT_0F_ENCODING_MAP(Xorpd, 0x66, 0x57, REG_DEF0_USE0), 3752637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Xorps, 0x00, 0x57, REG_DEF0_USE0), 3762637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Addsd, 0xF2, 0x58, REG_DEF0_USE0), 3772637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Addss, 0xF3, 0x58, REG_DEF0_USE0), 3782637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Mulsd, 0xF2, 0x59, REG_DEF0_USE0), 3792637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Mulss, 0xF3, 0x59, REG_DEF0_USE0), 380e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Cvtsd2ss, 0xF2, 0x5A, REG_DEF0), 381e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Cvtss2sd, 0xF3, 0x5A, REG_DEF0), 3822637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Subsd, 0xF2, 0x5C, REG_DEF0_USE0), 3832637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Subss, 0xF3, 0x5C, REG_DEF0_USE0), 3842637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Divsd, 0xF2, 0x5E, REG_DEF0_USE0), 3852637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Divss, 0xF3, 0x5E, REG_DEF0_USE0), 3862637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Punpckldq, 0x66, 0x62, REG_DEF0_USE0), 387fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Sqrtsd, 0xF2, 0x51, REG_DEF0_USE0), 388fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING2_MAP(Pmulld, 0x66, 0x38, 0x40, REG_DEF0_USE0), 389fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Pmullw, 0x66, 0xD5, REG_DEF0_USE0), 390fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Mulps, 0x00, 0x59, REG_DEF0_USE0), 391fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Mulpd, 0x66, 0x59, REG_DEF0_USE0), 392fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Paddb, 0x66, 0xFC, REG_DEF0_USE0), 393fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Paddw, 0x66, 0xFD, REG_DEF0_USE0), 394fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Paddd, 0x66, 0xFE, REG_DEF0_USE0), 395fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Addps, 0x00, 0x58, REG_DEF0_USE0), 396fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Addpd, 0xF2, 0x58, REG_DEF0_USE0), 397fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Psubb, 0x66, 0xF8, REG_DEF0_USE0), 398fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Psubw, 0x66, 0xF9, REG_DEF0_USE0), 399fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Psubd, 0x66, 0xFA, REG_DEF0_USE0), 400fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Subps, 0x00, 0x5C, REG_DEF0_USE0), 401fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Subpd, 0x66, 0x5C, REG_DEF0_USE0), 402fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Pand, 0x66, 0xDB, REG_DEF0_USE0), 403fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Por, 0x66, 0xEB, REG_DEF0_USE0), 404fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING_MAP(Pxor, 0x66, 0xEF, REG_DEF0_USE0), 405fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING2_MAP(Phaddw, 0x66, 0x38, 0x01, REG_DEF0_USE0), 406fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell EXT_0F_ENCODING2_MAP(Phaddd, 0x66, 0x38, 0x02, REG_DEF0_USE0), 407fb0fecffb31398adb6f74f58482f2c4aac95b9bfOlivier Come EXT_0F_ENCODING_MAP(Haddpd, 0x66, 0x7C, REG_DEF0_USE0), 408fb0fecffb31398adb6f74f58482f2c4aac95b9bfOlivier Come EXT_0F_ENCODING_MAP(Haddps, 0xF2, 0x7C, REG_DEF0_USE0), 409fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell 41035690630b82dc1dbf4a7ada37225893a550ea1e0Serguei Katkov { kX86PextrbRRI, kRegRegImmStore, IS_TERTIARY_OP | REG_DEF0 | REG_USE1, { 0x66, 0, 0x0F, 0x3A, 0x14, 0, 0, 1, false }, "PextbRRI", "!0r,!1r,!2d" }, 41160bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji { kX86PextrwRRI, kRegRegImm, IS_TERTIARY_OP | REG_DEF0 | REG_USE1, { 0x66, 0, 0x0F, 0xC5, 0x00, 0, 0, 1, false }, "PextwRRI", "!0r,!1r,!2d" }, 41235690630b82dc1dbf4a7ada37225893a550ea1e0Serguei Katkov { kX86PextrdRRI, kRegRegImmStore, IS_TERTIARY_OP | REG_DEF0 | REG_USE1, { 0x66, 0, 0x0F, 0x3A, 0x16, 0, 0, 1, false }, "PextdRRI", "!0r,!1r,!2d" }, 41360bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji { kX86PextrbMRI, kMemRegImm, IS_QUAD_OP | REG_USE02 | IS_STORE, { 0x66, 0, 0x0F, 0x3A, 0x16, 0, 0, 1, false }, "kX86PextrbMRI", "[!0r+!1d],!2r,!3d" }, 41460bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji { kX86PextrwMRI, kMemRegImm, IS_QUAD_OP | REG_USE02 | IS_STORE, { 0x66, 0, 0x0F, 0x3A, 0x16, 0, 0, 1, false }, "kX86PextrwMRI", "[!0r+!1d],!2r,!3d" }, 41560bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji { kX86PextrdMRI, kMemRegImm, IS_QUAD_OP | REG_USE02 | IS_STORE, { 0x66, 0, 0x0F, 0x3A, 0x16, 0, 0, 1, false }, "kX86PextrdMRI", "[!0r+!1d],!2r,!3d" }, 416fe94578b63380f464c3abd5c156b7b31d068db6cMark Mendell 4170f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PshuflwRRI, kRegRegImm, IS_TERTIARY_OP | REG_DEF0 | REG_USE1, { 0xF2, 0, 0x0F, 0x70, 0, 0, 0, 1, false }, "PshuflwRRI", "!0r,!1r,!2d" }, 4180f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PshufdRRI, kRegRegImm, IS_TERTIARY_OP | REG_DEF0 | REG_USE1, { 0x66, 0, 0x0F, 0x70, 0, 0, 0, 1, false }, "PshuffRRI", "!0r,!1r,!2d" }, 419b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 420fb0fecffb31398adb6f74f58482f2c4aac95b9bfOlivier Come { kX86ShufpsRRI, kRegRegImm, IS_TERTIARY_OP | REG_DEF0 | REG_USE1, { 0x00, 0, 0x0F, 0xC6, 0, 0, 0, 1, false }, "kX86ShufpsRRI", "!0r,!1r,!2d" }, 421fb0fecffb31398adb6f74f58482f2c4aac95b9bfOlivier Come { kX86ShufpdRRI, kRegRegImm, IS_TERTIARY_OP | REG_DEF0 | REG_USE1, { 0x66, 0, 0x0F, 0xC6, 0, 0, 0, 1, false }, "kX86ShufpdRRI", "!0r,!1r,!2d" }, 422b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 4230f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PsrawRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x71, 0, 4, 0, 1, false }, "PsrawRI", "!0r,!1d" }, 4240f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PsradRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x72, 0, 4, 0, 1, false }, "PsradRI", "!0r,!1d" }, 4250f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PsrlwRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x71, 0, 2, 0, 1, false }, "PsrlwRI", "!0r,!1d" }, 4260f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PsrldRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x72, 0, 2, 0, 1, false }, "PsrldRI", "!0r,!1d" }, 4270f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PsrlqRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x73, 0, 2, 0, 1, false }, "PsrlqRI", "!0r,!1d" }, 4280f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PsllwRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x71, 0, 6, 0, 1, false }, "PsllwRI", "!0r,!1d" }, 4290f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PslldRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x72, 0, 6, 0, 1, false }, "PslldRI", "!0r,!1d" }, 4300f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PsllqRI, kRegImm, IS_BINARY_OP | REG_DEF0_USE0, { 0x66, 0, 0x0F, 0x73, 0, 6, 0, 1, false }, "PsllqRI", "!0r,!1d" }, 431614c2b4e219631e8c190fd9fd5d4d9cd343434e1Razvan A Lupusoru 432bd3682eada753de52975ae2b4a712bd87dc139a6Alexei Zavjalov { kX86Fild32M, kMem, IS_LOAD | IS_UNARY_OP | REG_USE0 | USE_FP_STACK, { 0x0, 0, 0xDB, 0x00, 0, 0, 0, 0, false }, "Fild32M", "[!0r,!1d]" }, 433bd3682eada753de52975ae2b4a712bd87dc139a6Alexei Zavjalov { kX86Fild64M, kMem, IS_LOAD | IS_UNARY_OP | REG_USE0 | USE_FP_STACK, { 0x0, 0, 0xDF, 0x00, 0, 5, 0, 0, false }, "Fild64M", "[!0r,!1d]" }, 434bd3682eada753de52975ae2b4a712bd87dc139a6Alexei Zavjalov { kX86Fld32M, kMem, IS_LOAD | IS_UNARY_OP | REG_USE0 | USE_FP_STACK, { 0x0, 0, 0xD9, 0x00, 0, 0, 0, 0, false }, "Fld32M", "[!0r,!1d]" }, 435bd3682eada753de52975ae2b4a712bd87dc139a6Alexei Zavjalov { kX86Fld64M, kMem, IS_LOAD | IS_UNARY_OP | REG_USE0 | USE_FP_STACK, { 0x0, 0, 0xDD, 0x00, 0, 0, 0, 0, false }, "Fld64M", "[!0r,!1d]" }, 436bd3682eada753de52975ae2b4a712bd87dc139a6Alexei Zavjalov { kX86Fstp32M, kMem, IS_STORE | IS_UNARY_OP | REG_USE0 | USE_FP_STACK, { 0x0, 0, 0xD9, 0x00, 0, 3, 0, 0, false }, "Fstps32M", "[!0r,!1d]" }, 437bd3682eada753de52975ae2b4a712bd87dc139a6Alexei Zavjalov { kX86Fstp64M, kMem, IS_STORE | IS_UNARY_OP | REG_USE0 | USE_FP_STACK, { 0x0, 0, 0xDD, 0x00, 0, 3, 0, 0, false }, "Fstpd64M", "[!0r,!1d]" }, 438e63d9d4e42e659a365a9a06b910852ebc297f457Serguei Katkov { kX86Fst32M, kMem, IS_STORE | IS_UNARY_OP | REG_USE0 | USE_FP_STACK, { 0x0, 0, 0xD9, 0x00, 0, 2, 0, 0, false }, "Fsts32M", "[!0r,!1d]" }, 439e63d9d4e42e659a365a9a06b910852ebc297f457Serguei Katkov { kX86Fst64M, kMem, IS_STORE | IS_UNARY_OP | REG_USE0 | USE_FP_STACK, { 0x0, 0, 0xDD, 0x00, 0, 2, 0, 0, false }, "Fstd64M", "[!0r,!1d]" }, 440bd3682eada753de52975ae2b4a712bd87dc139a6Alexei Zavjalov { kX86Fprem, kNullary, NO_OPERAND | USE_FP_STACK, { 0xD9, 0, 0xF8, 0, 0, 0, 0, 0, false }, "Fprem64", "" }, 441bd3682eada753de52975ae2b4a712bd87dc139a6Alexei Zavjalov { kX86Fucompp, kNullary, NO_OPERAND | USE_FP_STACK, { 0xDA, 0, 0xE9, 0, 0, 0, 0, 0, false }, "Fucompp", "" }, 44201a50d660bd1fa692b132a24ec0f18f402e69de2Mark Mendell { kX86Fstsw16R, kNullary, NO_OPERAND | REG_DEFA | USE_FP_STACK, { 0x9B, 0xDF, 0xE0, 0, 0, 0, 0, 0, false }, "Fstsw16R", "ax" }, 443b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers 444d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell EXT_0F_ENCODING_MAP(Mova128, 0x66, 0x6F, REG_DEF0), 4450f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mova128MR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0x66, 0, 0x0F, 0x6F, 0, 0, 0, 0, false }, "Mova128MR", "[!0r+!1d],!2r" }, 4460f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mova128AR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0x66, 0, 0x0F, 0x6F, 0, 0, 0, 0, false }, "Mova128AR", "[!0r+!1r<<!2d+!3d],!4r" }, 447d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell 448d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell 4492c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru EXT_0F_ENCODING_MAP(Movups, 0x0, 0x10, REG_DEF0), 4500f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovupsMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0x0, 0, 0x0F, 0x11, 0, 0, 0, 0, false }, "MovupsMR", "[!0r+!1d],!2r" }, 4510f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovupsAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0x0, 0, 0x0F, 0x11, 0, 0, 0, 0, false }, "MovupsAR", "[!0r+!1r<<!2d+!3d],!4r" }, 4522c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 4532c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru EXT_0F_ENCODING_MAP(Movaps, 0x0, 0x28, REG_DEF0), 4540f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovapsMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0x0, 0, 0x0F, 0x29, 0, 0, 0, 0, false }, "MovapsMR", "[!0r+!1d],!2r" }, 4550f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovapsAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0x0, 0, 0x0F, 0x29, 0, 0, 0, 0, false }, "MovapsAR", "[!0r+!1r<<!2d+!3d],!4r" }, 4562c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 4570f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovlpsRM, kRegMem, IS_LOAD | IS_TERTIARY_OP | REG_DEF0 | REG_USE01, { 0x0, 0, 0x0F, 0x12, 0, 0, 0, 0, false }, "MovlpsRM", "!0r,[!1r+!2d]" }, 4580f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovlpsRA, kRegArray, IS_LOAD | IS_QUIN_OP | REG_DEF0 | REG_USE012, { 0x0, 0, 0x0F, 0x12, 0, 0, 0, 0, false }, "MovlpsRA", "!0r,[!1r+!2r<<!3d+!4d]" }, 4590f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovlpsMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0x0, 0, 0x0F, 0x13, 0, 0, 0, 0, false }, "MovlpsMR", "[!0r+!1d],!2r" }, 4600f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovlpsAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0x0, 0, 0x0F, 0x13, 0, 0, 0, 0, false }, "MovlpsAR", "[!0r+!1r<<!2d+!3d],!4r" }, 4612c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 4620f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovhpsRM, kRegMem, IS_LOAD | IS_TERTIARY_OP | REG_DEF0 | REG_USE01, { 0x0, 0, 0x0F, 0x16, 0, 0, 0, 0, false }, "MovhpsRM", "!0r,[!1r+!2d]" }, 4630f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovhpsRA, kRegArray, IS_LOAD | IS_QUIN_OP | REG_DEF0 | REG_USE012, { 0x0, 0, 0x0F, 0x16, 0, 0, 0, 0, false }, "MovhpsRA", "!0r,[!1r+!2r<<!3d+!4d]" }, 4640f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovhpsMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0x0, 0, 0x0F, 0x17, 0, 0, 0, 0, false }, "MovhpsMR", "[!0r+!1d],!2r" }, 4650f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovhpsAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0x0, 0, 0x0F, 0x17, 0, 0, 0, 0, false }, "MovhpsAR", "[!0r+!1r<<!2d+!3d],!4r" }, 4662c498d1f28e62e81fbdb477ff93ca7454e7493d7Razvan A Lupusoru 467e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Movdxr, 0x66, 0x6E, REG_DEF0), 468e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu EXT_0F_REX_W_ENCODING_MAP(Movqxr, 0x66, 0x6E, REG_DEF0), 4690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovqrxRR, kRegRegStore, IS_BINARY_OP | REG_DEF0 | REG_USE1, { 0x66, REX_W, 0x0F, 0x7E, 0, 0, 0, 0, false }, "MovqrxRR", "!0r,!1r" }, 4700f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovqrxMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0x66, REX_W, 0x0F, 0x7E, 0, 0, 0, 0, false }, "MovqrxMR", "[!0r+!1d],!2r" }, 4710f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovqrxAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0x66, REX_W, 0x0F, 0x7E, 0, 0, 0, 0, false }, "MovqrxAR", "[!0r+!1r<<!2d+!3d],!4r" }, 472e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 4730f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovdrxRR, kRegRegStore, IS_BINARY_OP | REG_DEF0 | REG_USE1, { 0x66, 0, 0x0F, 0x7E, 0, 0, 0, 0, false }, "MovdrxRR", "!0r,!1r" }, 4740f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovdrxMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02, { 0x66, 0, 0x0F, 0x7E, 0, 0, 0, 0, false }, "MovdrxMR", "[!0r+!1d],!2r" }, 4750f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovdrxAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014, { 0x66, 0, 0x0F, 0x7E, 0, 0, 0, 0, false }, "MovdrxAR", "[!0r+!1r<<!2d+!3d],!4r" }, 476b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 4770f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovsxdRR, kRegReg, IS_BINARY_OP | REG_DEF0 | REG_USE1, { REX_W, 0, 0x63, 0, 0, 0, 0, 0, false }, "MovsxdRR", "!0r,!1r" }, 4780f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovsxdRM, kRegMem, IS_LOAD | IS_TERTIARY_OP | REG_DEF0 | REG_USE1, { REX_W, 0, 0x63, 0, 0, 0, 0, 0, false }, "MovsxdRM", "!0r,[!1r+!2d]" }, 4790f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86MovsxdRA, kRegArray, IS_LOAD | IS_QUIN_OP | REG_DEF0 | REG_USE12, { REX_W, 0, 0x63, 0, 0, 0, 0, 0, false }, "MovsxdRA", "!0r,[!1r+!2r<<!3d+!4d]" }, 480e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu 4812bc477043b6ab2d7b4719ba8debf0a6a5b10c225Mark Mendell { kX86Set8R, kRegCond, IS_BINARY_OP | REG_DEF0 | REG_USE0 | USES_CCODES, { 0, 0, 0x0F, 0x90, 0, 0, 0, 0, true }, "Set8R", "!1c !0r" }, 4820f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Set8M, kMemCond, IS_STORE | IS_TERTIARY_OP | REG_USE0 | USES_CCODES, { 0, 0, 0x0F, 0x90, 0, 0, 0, 0, false }, "Set8M", "!2c [!0r+!1d]" }, 4830f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Set8A, kArrayCond, IS_STORE | IS_QUIN_OP | REG_USE01 | USES_CCODES, { 0, 0, 0x0F, 0x90, 0, 0, 0, 0, false }, "Set8A", "!4c [!0r+!1r<<!2d+!3d]" }, 484b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 485c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers // TODO: load/store? 486c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers // Encode the modrm opcode as an extra opcode byte to avoid computation during assembly. 4870f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Mfence, kReg, NO_OPERAND, { 0, 0, 0x0F, 0xAE, 0, 6, 0, 0, false }, "Mfence", "" }, 488c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers 4892637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Imul16, 0x66, 0xAF, REG_USE0 | REG_DEF0 | SETS_CCODES), 4902637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EXT_0F_ENCODING_MAP(Imul32, 0x00, 0xAF, REG_USE0 | REG_DEF0 | SETS_CCODES), 491e0ccdc0dd166136cd43e5f54201179a4496d33e8Chao-ying Fu EXT_0F_ENCODING_MAP(Imul64, REX_W, 0xAF, REG_USE0 | REG_DEF0 | SETS_CCODES), 4928302576126efae240eb21c7545cda7982437bd26jeffhao 4930f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86CmpxchgRR, kRegRegStore, IS_BINARY_OP | REG_DEF0 | REG_USE01 | REG_DEFA_USEA | SETS_CCODES, { 0, 0, 0x0F, 0xB1, 0, 0, 0, 0, false }, "Cmpxchg", "!0r,!1r" }, 4940f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86CmpxchgMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02 | REG_DEFA_USEA | SETS_CCODES, { 0, 0, 0x0F, 0xB1, 0, 0, 0, 0, false }, "Cmpxchg", "[!0r+!1d],!2r" }, 4950f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86CmpxchgAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014 | REG_DEFA_USEA | SETS_CCODES, { 0, 0, 0x0F, 0xB1, 0, 0, 0, 0, false }, "Cmpxchg", "[!0r+!1r<<!2d+!3d],!4r" }, 4960f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86LockCmpxchgMR, kMemReg, IS_STORE | IS_TERTIARY_OP | REG_USE02 | REG_DEFA_USEA | SETS_CCODES, { 0xF0, 0, 0x0F, 0xB1, 0, 0, 0, 0, false }, "Lock Cmpxchg", "[!0r+!1d],!2r" }, 4970f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86LockCmpxchgAR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014 | REG_DEFA_USEA | SETS_CCODES, { 0xF0, 0, 0x0F, 0xB1, 0, 0, 0, 0, false }, "Lock Cmpxchg", "[!0r+!1r<<!2d+!3d],!4r" }, 498c5e4ce116e4d44bfdf162f0c949e77772d7e0654nikolay serdjuk { kX86LockCmpxchg64AR, kArrayReg, IS_STORE | IS_QUIN_OP | REG_USE014 | REG_DEFA_USEA | SETS_CCODES, { 0xF0, REX_W, 0x0F, 0xB1, 0, 0, 0, 0, false }, "Lock Cmpxchg", "[!0r+!1r<<!2d+!3d],!4r" }, 4990f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86LockCmpxchg64M, kMem, IS_STORE | IS_BINARY_OP | REG_USE0 | REG_DEFAD_USEAD | REG_USEC | REG_USEB | SETS_CCODES, { 0xF0, 0, 0x0F, 0xC7, 0, 1, 0, 0, false }, "Lock Cmpxchg8b", "[!0r+!1d]" }, 5000f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86LockCmpxchg64A, kArray, IS_STORE | IS_QUAD_OP | REG_USE01 | REG_DEFAD_USEAD | REG_USEC | REG_USEB | SETS_CCODES, { 0xF0, 0, 0x0F, 0xC7, 0, 1, 0, 0, false }, "Lock Cmpxchg8b", "[!0r+!1r<<!2d+!3d]" }, 5010f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86XchgMR, kMemReg, IS_STORE | IS_LOAD | IS_TERTIARY_OP | REG_DEF2 | REG_USE02, { 0, 0, 0x87, 0, 0, 0, 0, 0, false }, "Xchg", "[!0r+!1d],!2r" }, 5028302576126efae240eb21c7545cda7982437bd26jeffhao 503021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu EXT_0F_R8_FORM_ENCODING_MAP(Movzx8, 0x00, 0xB6, REG_DEF0), 504e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Movzx16, 0x00, 0xB7, REG_DEF0), 505021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu EXT_0F_R8_FORM_ENCODING_MAP(Movsx8, 0x00, 0xBE, REG_DEF0), 506e296248a124ed8287b38a9225463696c18d84cd6jeffhao EXT_0F_ENCODING_MAP(Movsx16, 0x00, 0xBF, REG_DEF0), 50794f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov EXT_0F_ENCODING_MAP(Movzx8q, REX_W, 0xB6, REG_DEF0), 50894f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov EXT_0F_ENCODING_MAP(Movzx16q, REX_W, 0xB7, REG_DEF0), 50994f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov EXT_0F_ENCODING_MAP(Movsx8q, REX, 0xBE, REG_DEF0), 51094f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov EXT_0F_ENCODING_MAP(Movsx16q, REX_W, 0xBF, REG_DEF0), 511b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers#undef EXT_0F_ENCODING_MAP 512b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 5130f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Jcc8, kJcc, IS_BINARY_OP | IS_BRANCH | NEEDS_FIXUP | USES_CCODES, { 0, 0, 0x70, 0, 0, 0, 0, 0, false }, "Jcc8", "!1c !0t" }, 5140f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Jcc32, kJcc, IS_BINARY_OP | IS_BRANCH | NEEDS_FIXUP | USES_CCODES, { 0, 0, 0x0F, 0x80, 0, 0, 0, 0, false }, "Jcc32", "!1c !0t" }, 5150f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Jmp8, kJmp, IS_UNARY_OP | IS_BRANCH | NEEDS_FIXUP, { 0, 0, 0xEB, 0, 0, 0, 0, 0, false }, "Jmp8", "!0t" }, 5160f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Jmp32, kJmp, IS_UNARY_OP | IS_BRANCH | NEEDS_FIXUP, { 0, 0, 0xE9, 0, 0, 0, 0, 0, false }, "Jmp32", "!0t" }, 5170f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86JmpR, kJmp, IS_UNARY_OP | IS_BRANCH | REG_USE0, { 0, 0, 0xFF, 0, 0, 4, 0, 0, false }, "JmpR", "!0r" }, 5180f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Jecxz8, kJmp, NO_OPERAND | IS_BRANCH | NEEDS_FIXUP | REG_USEC, { 0, 0, 0xE3, 0, 0, 0, 0, 0, false }, "Jecxz", "!0t" }, 5190f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86JmpT, kJmp, IS_UNARY_OP | IS_BRANCH | IS_LOAD, { THREAD_PREFIX, 0, 0xFF, 0, 0, 4, 0, 0, false }, "JmpT", "fs:[!0d]" }, 5200f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86CallR, kCall, IS_UNARY_OP | IS_BRANCH | REG_USE0, { 0, 0, 0xE8, 0, 0, 0, 0, 0, false }, "CallR", "!0r" }, 5210f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86CallM, kCall, IS_BINARY_OP | IS_BRANCH | IS_LOAD | REG_USE0, { 0, 0, 0xFF, 0, 0, 2, 0, 0, false }, "CallM", "[!0r+!1d]" }, 5220f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86CallA, kCall, IS_QUAD_OP | IS_BRANCH | IS_LOAD | REG_USE01, { 0, 0, 0xFF, 0, 0, 2, 0, 0, false }, "CallA", "[!0r+!1r<<!2d+!3d]" }, 5230f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86CallT, kCall, IS_UNARY_OP | IS_BRANCH | IS_LOAD, { THREAD_PREFIX, 0, 0xFF, 0, 0, 2, 0, 0, false }, "CallT", "fs:[!0d]" }, 5240f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86CallI, kCall, IS_UNARY_OP | IS_BRANCH, { 0, 0, 0xE8, 0, 0, 0, 0, 4, false }, "CallI", "!0d" }, 5250f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86Ret, kNullary, NO_OPERAND | IS_BRANCH, { 0, 0, 0xC3, 0, 0, 0, 0, 0, false }, "Ret", "" }, 5260f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 5270f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86StartOfMethod, kMacro, IS_UNARY_OP | SETS_CCODES, { 0, 0, 0, 0, 0, 0, 0, 0, false }, "StartOfMethod", "!0r" }, 5280f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PcRelLoadRA, kPcRel, IS_LOAD | IS_QUIN_OP | REG_DEF0_USE12, { 0, 0, 0x8B, 0, 0, 0, 0, 0, false }, "PcRelLoadRA", "!0r,[!1r+!2r<<!3d+!4p]" }, 5290f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86PcRelAdr, kPcRel, IS_LOAD | IS_BINARY_OP | REG_DEF0, { 0, 0, 0xB8, 0, 0, 0, 0, 4, false }, "PcRelAdr", "!0r,!1d" }, 5300f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers { kX86RepneScasw, kNullary, NO_OPERAND | REG_USEA | REG_USEC | SETS_CCODES, { 0x66, 0xF2, 0xAF, 0, 0, 0, 0, 0, false }, "RepNE ScasW", "" }, 531e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee}; 532e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 5330f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersstatic bool NeedsRex(int32_t raw_reg) { 5340f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return RegStorage::RegNum(raw_reg) > 7; 5350f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers} 5360f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 5370f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersstatic uint8_t LowRegisterBits(int32_t raw_reg) { 5380f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = RegStorage::RegNum(raw_reg) & kRegNumMask32; // 3 bits 5390f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_LT(low_reg, 8); 5400f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return low_reg; 5410f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers} 5420f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 5435aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogersstatic bool HasModrm(const X86EncodingMap* entry) { 5445aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers switch (entry->kind) { 5455aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kNullary: return false; 5465aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegOpcode: return false; 5475aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers default: return true; 5485aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 5495aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers} 5505aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers 5515aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogersstatic bool HasSib(const X86EncodingMap* entry) { 5525aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers switch (entry->kind) { 5535aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kArray: return true; 5545aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kArrayReg: return true; 5555aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegArray: return true; 5565aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kArrayImm: return true; 5575aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegArrayImm: return true; 5585aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kShiftArrayImm: return true; 5595aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kShiftArrayCl: return true; 5605aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kArrayCond: return true; 5615aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kCall: 5625aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers switch (entry->opcode) { 5635aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kX86CallA: return true; 5645aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers default: return false; 5655aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 5665aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kPcRel: return true; 5675aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers switch (entry->opcode) { 5685aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kX86PcRelLoadRA: return true; 5695aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers default: return false; 5705aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 5715aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers default: return false; 5725aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 5735aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers} 5745aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers 5755aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogersstatic bool ModrmIsRegReg(const X86EncodingMap* entry) { 5765aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers switch (entry->kind) { 5775aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers // There is no modrm for this kind of instruction, therefore the reg doesn't form part of the 5785aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers // modrm: 5795aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kNullary: return true; 5805aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegOpcode: return true; 5815aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kMovRegImm: return true; 5825aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers // Regular modrm value of 3 cases, when there is one register the other register holds an 5835aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers // opcode so the base register is special. 5845aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kReg: return true; 5855aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegReg: return true; 5865aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegRegStore: return true; 5875aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegImm: return true; 5885aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegRegImm: return true; 5895aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegRegImmStore: return true; 5905aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kShiftRegImm: return true; 5915aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kShiftRegCl: return true; 5925aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegCond: return true; 5935aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kRegRegCond: return true; 5945aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kJmp: 5955aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers switch (entry->opcode) { 5965aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kX86JmpR: return true; 5975aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers default: return false; 5985aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 5995aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kCall: 6005aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers switch (entry->opcode) { 6015aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers case kX86CallR: return true; 6025aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers default: return false; 6035aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 6045aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers default: return false; 6055aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 6065aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers} 6075aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers 608021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fustatic bool IsByteSecondOperand(const X86EncodingMap* entry) { 609021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu return StartsWith(entry->name, "Movzx8") || StartsWith(entry->name, "Movsx8"); 610021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu} 611021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu 6120f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogerssize_t X86Mir2Lir::ComputeSize(const X86EncodingMap* entry, int32_t raw_reg, int32_t raw_index, 6135aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers int32_t raw_base, int32_t displacement) { 6145aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers bool has_modrm = HasModrm(entry); 6155aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers bool has_sib = HasSib(entry); 6165aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers bool r8_form = entry->skeleton.r8_form; 6175aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers bool modrm_is_reg_reg = ModrmIsRegReg(entry); 6185aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers if (has_sib) { 6195aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers DCHECK(!modrm_is_reg_reg); 6205aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 621b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers size_t size = 0; 622b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (entry->skeleton.prefix1 > 0) { 623b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers ++size; 624b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (entry->skeleton.prefix2 > 0) { 625b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers ++size; 626b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 627b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 628dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina if (cu_->target64 || kIsDebugBuild) { 6295aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers bool registers_need_rex_prefix = NeedsRex(raw_reg) || NeedsRex(raw_index) || NeedsRex(raw_base); 6305aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers if (r8_form) { 6315aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers // Do we need an empty REX prefix to normalize byte registers? 632021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu registers_need_rex_prefix = registers_need_rex_prefix || 633021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu (RegStorage::RegNum(raw_reg) >= 4 && !IsByteSecondOperand(entry)); 6345aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers registers_need_rex_prefix = registers_need_rex_prefix || 6355aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers (modrm_is_reg_reg && (RegStorage::RegNum(raw_base) >= 4)); 6365aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 6375aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers if (registers_need_rex_prefix) { 638dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina DCHECK(cu_->target64) << "Attempt to use a 64-bit only addressable register " 6395aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers << RegStorage::RegNum(raw_reg) << " with instruction " << entry->name; 64094f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov if (entry->skeleton.prefix1 != REX_W && entry->skeleton.prefix2 != REX_W 64194f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov && entry->skeleton.prefix1 != REX && entry->skeleton.prefix2 != REX) { 6425aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers ++size; // rex 6435aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 6440f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } 645a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } 646b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers ++size; // opcode 647b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (entry->skeleton.opcode == 0x0F) { 648b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers ++size; 649b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (entry->skeleton.extra_opcode1 == 0x38 || entry->skeleton.extra_opcode1 == 0x3A) { 650b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers ++size; 651b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 652b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 6535aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers if (has_modrm) { 6545aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers ++size; // modrm 655b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 6565aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers if (!modrm_is_reg_reg) { 6575aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers if (has_sib || LowRegisterBits(raw_base) == rs_rX86_SP.GetRegNum() 658dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina || (cu_->target64 && entry->skeleton.prefix1 == THREAD_PREFIX)) { 6595aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers // SP requires a SIB byte. 6605aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers // GS access also needs a SIB byte for absolute adressing in 64-bit mode. 6615aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers ++size; 6625aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 6635aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers if (displacement != 0 || LowRegisterBits(raw_base) == rs_rBP.GetRegNum()) { 6645aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers // BP requires an explicit displacement, even when it's 0. 6655aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers if (entry->opcode != kX86Lea32RA && entry->opcode != kX86Lea64RA) { 6665aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers DCHECK_NE(entry->flags & (IS_LOAD | IS_STORE), UINT64_C(0)) << entry->name; 6675aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers } 6685aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers size += IS_SIMM8(displacement) ? 1 : 4; 669b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 670b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 671b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers size += entry->skeleton.immediate_bytes; 672b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return size; 673b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 674b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 6755aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogerssize_t X86Mir2Lir::GetInsnSize(LIR* lir) { 676409fe94ad529d9334587be80b9f6a3d166805508buzbee DCHECK(!IsPseudoLirOp(lir->opcode)); 6771fd3346740dfb7f47be9922312b68a4227fada96buzbee const X86EncodingMap* entry = &X86Mir2Lir::EncodingMap[lir->opcode]; 6780f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(entry->opcode, lir->opcode) << entry->name; 6795aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers 680b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers switch (entry->kind) { 681de797834a282bf913e144f83ff044efd6d77b278Ian Rogers case kData: 6820f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return 4; // 4 bytes of data. 683b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kNop: 6840f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return lir->operands[0]; // Length of nop is sole operand. 685b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kNullary: 6865aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, NO_REG, 0); 687a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko case kRegOpcode: // lir operands - 0: reg 6885aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, lir->operands[0], 0); 689b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kReg: // lir operands - 0: reg 6905aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, lir->operands[0], 0); 6919bd02818fb88937bafcd1bf66334c0e8617f02bfJeff Hao case kMem: // lir operands - 0: base, 1: disp 6925aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, lir->operands[0], lir->operands[1]); 693b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kArray: // lir operands - 0: base, 1: index, 2: scale, 3: disp 6945aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, lir->operands[1], lir->operands[0], lir->operands[3]); 6959bd02818fb88937bafcd1bf66334c0e8617f02bfJeff Hao case kMemReg: // lir operands - 0: base, 1: disp, 2: reg 6965aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[2], NO_REG, lir->operands[0], lir->operands[1]); 6972637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell case kMemRegImm: // lir operands - 0: base, 1: disp, 2: reg 3: immediate 6985aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[2], NO_REG, lir->operands[0], lir->operands[1]); 699b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kArrayReg: // lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg 7000f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return ComputeSize(entry, lir->operands[4], lir->operands[1], lir->operands[0], 7015aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers lir->operands[3]); 702b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kThreadReg: // lir operands - 0: disp, 1: reg 7030f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Thread displacement size is always 32bit. 7045aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[1], NO_REG, NO_REG, 0x12345678); 705a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko case kRegReg: // lir operands - 0: reg1, 1: reg2 7065aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[0], NO_REG, lir->operands[1], 0); 707a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko case kRegRegStore: // lir operands - 0: reg2, 1: reg1 7085aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[1], NO_REG, lir->operands[0], 0); 7099bd02818fb88937bafcd1bf66334c0e8617f02bfJeff Hao case kRegMem: // lir operands - 0: reg, 1: base, 2: disp 7105aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[0], NO_REG, lir->operands[1], lir->operands[2]); 7119bd02818fb88937bafcd1bf66334c0e8617f02bfJeff Hao case kRegArray: // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp 7120f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return ComputeSize(entry, lir->operands[0], lir->operands[2], lir->operands[1], 7135aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers lir->operands[4]); 714b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kRegThread: // lir operands - 0: reg, 1: disp 7150f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Thread displacement size is always 32bit. 7165aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[0], NO_REG, NO_REG, 0x12345678); 717b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kRegImm: { // lir operands - 0: reg, 1: immediate 7185aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers size_t size = ComputeSize(entry, lir->operands[0], NO_REG, NO_REG, 0); 7190f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // AX opcodes don't require the modrm byte. 720b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (entry->skeleton.ax_opcode == 0) { 721b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers return size; 722b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 7230f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return size - (RegStorage::RegNum(lir->operands[0]) == rs_rAX.GetRegNum() ? 1 : 0); 724b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 725de797834a282bf913e144f83ff044efd6d77b278Ian Rogers } 726b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kMemImm: // lir operands - 0: base, 1: disp, 2: immediate 7275aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, lir->operands[0], lir->operands[1]); 728b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kArrayImm: // lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate 7295aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, lir->operands[1], lir->operands[0], lir->operands[3]); 730b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kThreadImm: // lir operands - 0: disp, 1: imm 7310f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Thread displacement size is always 32bit. 7325aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, NO_REG, 0x12345678); 7330f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kRegRegImm: // lir operands - 0: reg1, 1: reg2, 2: imm 7340f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Note: RegRegImm form passes reg2 as index but encodes it using base. 7355aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[0], lir->operands[1], NO_REG, 0); 7360f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kRegRegImmStore: // lir operands - 0: reg2, 1: reg1, 2: imm 7370f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Note: RegRegImmStore form passes reg1 as index but encodes it using base. 7385aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[1], lir->operands[0], NO_REG, 0); 739b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kRegMemImm: // lir operands - 0: reg, 1: base, 2: disp, 3: imm 7405aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[0], NO_REG, lir->operands[1], lir->operands[2]); 741b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kRegArrayImm: // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp, 5: imm 7420f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return ComputeSize(entry, lir->operands[0], lir->operands[2], lir->operands[1], 7435aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers lir->operands[4]); 744b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kMovRegImm: // lir operands - 0: reg, 1: immediate 7455192cbb12856b12620dc346758605baaa1469cedYixin Shou case kMovRegQuadImm: 7460f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return ((entry->skeleton.prefix1 != 0 || NeedsRex(lir->operands[0])) ? 1 : 0) + 1 + 7470f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers entry->skeleton.immediate_bytes; 748b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kShiftRegImm: // lir operands - 0: reg, 1: immediate 749b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // Shift by immediate one has a shorter opcode. 7505aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[0], NO_REG, NO_REG, 0) - 7510f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers (lir->operands[1] == 1 ? 1 : 0); 752b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kShiftMemImm: // lir operands - 0: base, 1: disp, 2: immediate 753b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // Shift by immediate one has a shorter opcode. 7545aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, lir->operands[0], lir->operands[1]) - 7550f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers (lir->operands[2] == 1 ? 1 : 0); 756b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kShiftArrayImm: // lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate 757b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // Shift by immediate one has a shorter opcode. 7585aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, lir->operands[1], lir->operands[0], lir->operands[3]) - 7590f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers (lir->operands[4] == 1 ? 1 : 0); 760a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko case kShiftRegCl: // lir operands - 0: reg, 1: cl 7610f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(rs_rCX.GetRegNum(), RegStorage::RegNum(lir->operands[1])); 7620f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Note: ShiftRegCl form passes reg as reg but encodes it using base. 7635aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[0], NO_REG, NO_REG, 0); 764b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kShiftMemCl: // lir operands - 0: base, 1: disp, 2: cl 7650f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(rs_rCX.GetRegNum(), RegStorage::RegNum(lir->operands[2])); 7665aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, lir->operands[0], lir->operands[1]); 7670f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kShiftArrayCl: // lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: cl 7680f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(rs_rCX.GetRegNum(), RegStorage::RegNum(lir->operands[4])); 7690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return ComputeSize(entry, lir->operands[4], lir->operands[1], lir->operands[0], 7705aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers lir->operands[3]); 771b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kRegCond: // lir operands - 0: reg, 1: cond 7725aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, lir->operands[0], 0); 773b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kMemCond: // lir operands - 0: base, 1: disp, 2: cond 7745aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, lir->operands[0], lir->operands[1]); 775b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kArrayCond: // lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: cond 7760f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 7775aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, lir->operands[1], lir->operands[0], lir->operands[3]); 7780f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kRegRegCond: // lir operands - 0: reg1, 1: reg2, 2: cond 7790f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 7805aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[0], NO_REG, lir->operands[1], 0); 7810f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kRegMemCond: // lir operands - 0: reg, 1: base, 2: disp, 3:cond 7820f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 7835aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, lir->operands[0], NO_REG, lir->operands[1], lir->operands[2]); 784b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers case kJcc: 785b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (lir->opcode == kX86Jcc8) { 786b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers return 2; // opcode + rel8 787b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 788b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers DCHECK(lir->opcode == kX86Jcc32); 789b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers return 6; // 2 byte opcode + rel32 790b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 791b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers case kJmp: 7924028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell if (lir->opcode == kX86Jmp8 || lir->opcode == kX86Jecxz8) { 793b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers return 2; // opcode + rel8 7947caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } else if (lir->opcode == kX86Jmp32) { 795b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers return 5; // opcode + rel32 79660d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom } else if (lir->opcode == kX86JmpT) { 7970f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Thread displacement size is always 32bit. 7985aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, NO_REG, 0x12345678); 7997caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } else { 8007caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK(lir->opcode == kX86JmpR); 801a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko if (NeedsRex(lir->operands[0])) { 802a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko return 3; // REX.B + opcode + modrm 803a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } else { 804a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko return 2; // opcode + modrm 805a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } 806b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 807b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kCall: 808b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes switch (lir->opcode) { 80955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell case kX86CallI: return 5; // opcode 0:disp 810b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kX86CallR: return 2; // opcode modrm 811b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kX86CallM: // lir operands - 0: base, 1: disp 8125aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, lir->operands[0], lir->operands[1]); 813b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kX86CallA: // lir operands - 0: base, 1: index, 2: scale, 3: disp 8145aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, lir->operands[1], lir->operands[0], lir->operands[3]); 8156cbb2bd8ba9a52de7e50a5da1f4e98dd7a460f1bIan Rogers case kX86CallT: // lir operands - 0: disp 8160f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Thread displacement size is always 32bit. 8175aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers return ComputeSize(entry, NO_REG, NO_REG, NO_REG, 0x12345678); 818b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers default: 819b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 820b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 821b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 8227caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers case kPcRel: 8237caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers if (entry->opcode == kX86PcRelLoadRA) { 8247caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table 8250f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Force the displacement size to 32bit, it will hold a computed offset later. 8260f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return ComputeSize(entry, lir->operands[0], lir->operands[2], lir->operands[1], 8275aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers 0x12345678); 8287caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } else { 8290f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(entry->opcode, kX86PcRelAdr); 8307934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom return 5; // opcode with reg + 4 byte immediate 8317caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } 832a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko case kMacro: // lir operands - 0: reg 8337caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(lir->opcode, static_cast<int>(kX86StartOfMethod)); 8347caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers return 5 /* call opcode + 4 byte displacement */ + 1 /* pop reg */ + 835dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina ComputeSize(&X86Mir2Lir::EncodingMap[cu_->target64 ? kX86Sub64RI : kX86Sub32RI], 8365aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers lir->operands[0], NO_REG, NO_REG, 0) - 8370f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Shorter ax encoding. 8380f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers (RegStorage::RegNum(lir->operands[0]) == rs_rAX.GetRegNum() ? 1 : 0); 8390f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kUnimplemented: 840b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 841de797834a282bf913e144f83ff044efd6d77b278Ian Rogers } 842b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers UNIMPLEMENTED(FATAL) << "Unimplemented size encoding for: " << entry->name; 843de797834a282bf913e144f83ff044efd6d77b278Ian Rogers return 0; 844de797834a282bf913e144f83ff044efd6d77b278Ian Rogers} 845e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 8460f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersstatic uint8_t ModrmForDisp(int base, int disp) { 8470f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // BP requires an explicit disp, so do not omit it in the 0 case 8480f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers if (disp == 0 && RegStorage::RegNum(base) != rs_rBP.GetRegNum()) { 8490f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return 0; 8500f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } else if (IS_SIMM8(disp)) { 8510f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return 1; 8520f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } else { 8530f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers return 2; 8540f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } 8550f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers} 8560f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 8570f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::CheckValidByteRegister(const X86EncodingMap* entry, int32_t raw_reg) { 8580f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers if (kIsDebugBuild) { 8590f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Sanity check r8_form is correctly specified. 8600f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers if (entry->skeleton.r8_form) { 8610f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CHECK(strchr(entry->name, '8') != nullptr) << entry->name; 8620f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } else { 8630f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers if (entry->skeleton.immediate_bytes != 1) { // Ignore ...I8 instructions. 8641c55703526827b5fc63f5d4b8477f36574649342Serguei Katkov if (!StartsWith(entry->name, "Movzx8") && !StartsWith(entry->name, "Movsx8") 8651c55703526827b5fc63f5d4b8477f36574649342Serguei Katkov && !StartsWith(entry->name, "Movzx8q") && !StartsWith(entry->name, "Movsx8q")) { 8660f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CHECK(strchr(entry->name, '8') == nullptr) << entry->name; 8670f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } 8680f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } 8690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } 8700f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers if (RegStorage::RegNum(raw_reg) >= 4) { 8710f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // ah, bh, ch and dh are not valid registers in 32-bit. 872dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina CHECK(cu_->target64 || !entry->skeleton.r8_form) 8730f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers << "Invalid register " << static_cast<int>(RegStorage::RegNum(raw_reg)) 8740f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers << " for instruction " << entry->name << " in " 8750f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers << PrettyMethod(cu_->method_idx, *cu_->dex_file); 8760f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } 8770f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } 878a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko} 879a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko 880a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenkovoid X86Mir2Lir::EmitPrefix(const X86EncodingMap* entry, 8815aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers int32_t raw_reg_r, int32_t raw_reg_x, int32_t raw_reg_b) { 882a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko // REX.WRXB 883a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko // W - 64-bit operand 884a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko // R - MODRM.reg 885a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko // X - SIB.index 886a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko // B - MODRM.rm/SIB.base 887a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko bool w = (entry->skeleton.prefix1 == REX_W) || (entry->skeleton.prefix2 == REX_W); 8880f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers bool r = NeedsRex(raw_reg_r); 8890f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers bool x = NeedsRex(raw_reg_x); 8900f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers bool b = NeedsRex(raw_reg_b); 8915aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers bool r8_form = entry->skeleton.r8_form; 8925aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers bool modrm_is_reg_reg = ModrmIsRegReg(entry); 8935aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers 8940f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t rex = 0; 8957e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu if (r8_form) { 8967e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu // Do we need an empty REX prefix to normalize byte register addressing? 897021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu if (RegStorage::RegNum(raw_reg_r) >= 4 && !IsByteSecondOperand(entry)) { 8987e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu rex |= 0x40; // REX.0000 8997e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu } else if (modrm_is_reg_reg && RegStorage::RegNum(raw_reg_b) >= 4) { 9007e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu rex |= 0x40; // REX.0000 9017e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu } 9020f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers } 903a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko if (w) { 904a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko rex |= 0x48; // REX.W000 905a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } 906a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko if (r) { 907a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko rex |= 0x44; // REX.0R00 908a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } 909a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko if (x) { 910a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko rex |= 0x42; // REX.00X0 911a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } 912a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko if (b) { 913a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko rex |= 0x41; // REX.000B 914a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } 915057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko if (entry->skeleton.prefix1 != 0) { 916dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina if (cu_->target64 && entry->skeleton.prefix1 == THREAD_PREFIX) { 9170f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // 64 bit addresses by GS, not FS. 9189ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko code_buffer_.push_back(THREAD_PREFIX_GS); 9199ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } else { 92094f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov if (entry->skeleton.prefix1 == REX_W || entry->skeleton.prefix1 == REX) { 92194f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov DCHECK(cu_->target64); 922a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko rex |= entry->skeleton.prefix1; 923a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko code_buffer_.push_back(rex); 924a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko rex = 0; 925a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } else { 926a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko code_buffer_.push_back(entry->skeleton.prefix1); 927a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } 9289ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 929057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko if (entry->skeleton.prefix2 != 0) { 93094f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov if (entry->skeleton.prefix2 == REX_W || entry->skeleton.prefix1 == REX) { 93194f3eb0c757d0a6a145e24ef95ef7d35c091bb01Serguei Katkov DCHECK(cu_->target64); 932a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko rex |= entry->skeleton.prefix2; 933a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko code_buffer_.push_back(rex); 934a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko rex = 0; 935a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } else { 936a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko code_buffer_.push_back(entry->skeleton.prefix2); 937a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } 938057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko } 939057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko } else { 940057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_EQ(0, entry->skeleton.prefix2); 941057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko } 942a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko if (rex != 0) { 943dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina DCHECK(cu_->target64); 944a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko code_buffer_.push_back(rex); 945a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko } 946057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko} 947057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko 948057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Markovoid X86Mir2Lir::EmitOpcode(const X86EncodingMap* entry) { 949057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back(entry->skeleton.opcode); 950057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko if (entry->skeleton.opcode == 0x0F) { 951057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back(entry->skeleton.extra_opcode1); 952057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko if (entry->skeleton.extra_opcode1 == 0x38 || entry->skeleton.extra_opcode1 == 0x3A) { 953057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back(entry->skeleton.extra_opcode2); 954057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko } else { 955057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_EQ(0, entry->skeleton.extra_opcode2); 956057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko } 957057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko } else { 958057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_EQ(0, entry->skeleton.extra_opcode1); 959057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_EQ(0, entry->skeleton.extra_opcode2); 960057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko } 961057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko} 962057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko 963a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenkovoid X86Mir2Lir::EmitPrefixAndOpcode(const X86EncodingMap* entry, 9645aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers int32_t raw_reg_r, int32_t raw_reg_x, int32_t raw_reg_b) { 9655aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, raw_reg_r, raw_reg_x, raw_reg_b); 966057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko EmitOpcode(entry); 967057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko} 968057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko 9690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitDisp(uint8_t base, int32_t disp) { 970703f2cd1f4d1eb5ab5c9792ca2de9ffb39378203jeffhao // BP requires an explicit disp, so do not omit it in the 0 case 971091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee if (disp == 0 && RegStorage::RegNum(base) != rs_rBP.GetRegNum()) { 972b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return; 973b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else if (IS_SIMM8(disp)) { 9741fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(disp & 0xFF); 975b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 9761fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(disp & 0xFF); 9771fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 8) & 0xFF); 9781fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 16) & 0xFF); 9791fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 24) & 0xFF); 980b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 981b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 982b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 9839ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenkovoid X86Mir2Lir::EmitModrmThread(uint8_t reg_or_opcode) { 984dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina if (cu_->target64) { 9859ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko // Absolute adressing for GS access. 9869ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko uint8_t modrm = (0 << 6) | (reg_or_opcode << 3) | rs_rX86_SP.GetRegNum(); 9879ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko code_buffer_.push_back(modrm); 9889ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko uint8_t sib = (0/*TIMES_1*/ << 6) | (rs_rX86_SP.GetRegNum() << 3) | rs_rBP.GetRegNum(); 9899ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko code_buffer_.push_back(sib); 9909ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } else { 9919ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko uint8_t modrm = (0 << 6) | (reg_or_opcode << 3) | rs_rBP.GetRegNum(); 9929ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko code_buffer_.push_back(modrm); 9939ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko } 9949ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko} 9959ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko 9960f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitModrmDisp(uint8_t reg_or_opcode, uint8_t base, int32_t disp) { 9970f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_LT(reg_or_opcode, 8); 9980f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_LT(base, 8); 9990f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (ModrmForDisp(base, disp) << 6) | (reg_or_opcode << 3) | base; 1000057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back(modrm); 10010f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers if (base == rs_rX86_SP.GetRegNum()) { 1002057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko // Special SIB for SP base 1003091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee code_buffer_.push_back(0 << 6 | rs_rX86_SP.GetRegNum() << 3 | rs_rX86_SP.GetRegNum()); 1004a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko } 1005057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko EmitDisp(base, disp); 1006057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko} 1007057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko 1008057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Markovoid X86Mir2Lir::EmitModrmSibDisp(uint8_t reg_or_opcode, uint8_t base, uint8_t index, 10090f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int scale, int32_t disp) { 1010091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_LT(RegStorage::RegNum(reg_or_opcode), 8); 1011091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee uint8_t modrm = (ModrmForDisp(base, disp) << 6) | RegStorage::RegNum(reg_or_opcode) << 3 | 1012091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee rs_rX86_SP.GetRegNum(); 1013057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back(modrm); 1014057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_LT(scale, 4); 1015091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_LT(RegStorage::RegNum(index), 8); 1016091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee DCHECK_LT(RegStorage::RegNum(base), 8); 1017091cc408e9dc87e60fb64c61e186bea568fc3d3abuzbee uint8_t sib = (scale << 6) | (RegStorage::RegNum(index) << 3) | RegStorage::RegNum(base); 1018057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back(sib); 1019057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko EmitDisp(base, disp); 1020057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko} 1021057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko 102296992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenkovoid X86Mir2Lir::EmitImm(const X86EncodingMap* entry, int64_t imm) { 1023057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko switch (entry->skeleton.immediate_bytes) { 1024057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko case 1: 1025057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK(IS_SIMM8(imm)); 1026057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back(imm & 0xFF); 1027057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko break; 1028057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko case 2: 1029057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK(IS_SIMM16(imm)); 1030057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back(imm & 0xFF); 1031057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back((imm >> 8) & 0xFF); 1032057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko break; 1033057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko case 4: 10340f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK(IS_SIMM32(imm)); 1035057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back(imm & 0xFF); 1036057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back((imm >> 8) & 0xFF); 1037057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back((imm >> 16) & 0xFF); 1038057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko code_buffer_.push_back((imm >> 24) & 0xFF); 1039057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko break; 104096992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko case 8: 104196992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back(imm & 0xFF); 104296992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 8) & 0xFF); 104396992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 16) & 0xFF); 104496992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 24) & 0xFF); 104596992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 32) & 0xFF); 104696992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 40) & 0xFF); 104796992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 48) & 0xFF); 104896992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 56) & 0xFF); 104996992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko break; 1050057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko default: 1051057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko LOG(FATAL) << "Unexpected immediate bytes (" << entry->skeleton.immediate_bytes 1052057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko << ") for instruction: " << entry->name; 1053057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko break; 1054a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko } 1055057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko} 1056057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko 10570f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitNullary(const X86EncodingMap* entry) { 10580f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 10595aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, NO_REG, NO_REG); 10600f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(0, entry->skeleton.modrm_opcode); 10610f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 10620f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 10630f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers} 10640f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 10650f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitOpRegOpcode(const X86EncodingMap* entry, int32_t raw_reg) { 10660f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 10675aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, NO_REG, raw_reg); 1068057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko // There's no 3-byte instruction with +rd 1069057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK(entry->skeleton.opcode != 0x0F || 1070057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko (entry->skeleton.extra_opcode1 != 0x38 && entry->skeleton.extra_opcode1 != 0x3A)); 10710f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK(!RegStorage::IsFloat(raw_reg)); 10720f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 10730f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers code_buffer_.back() += low_reg; 1074a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko DCHECK_EQ(0, entry->skeleton.ax_opcode); 1075a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1076a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko} 1077a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko 10780f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitOpReg(const X86EncodingMap* entry, int32_t raw_reg) { 10790f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CheckValidByteRegister(entry, raw_reg); 10805aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, NO_REG, raw_reg); 10810f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 10820f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (3 << 6) | (entry->skeleton.modrm_opcode << 3) | low_reg; 10831fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(modrm); 1084b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 1085b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1086b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 1087b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 10880f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitOpMem(const X86EncodingMap* entry, int32_t raw_base, int32_t disp) { 10890f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 10905aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, NO_REG, NO_REG, raw_base); 10911fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(entry->skeleton.opcode); 1092057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_NE(0x0F, entry->skeleton.opcode); 1093b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.extra_opcode1); 1094b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.extra_opcode2); 10950f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 10960f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmDisp(entry->skeleton.modrm_opcode, low_base, disp); 1097057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_EQ(0, entry->skeleton.ax_opcode); 1098057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1099057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko} 1100057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko 11010f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitOpArray(const X86EncodingMap* entry, int32_t raw_base, int32_t raw_index, 11020f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int scale, int32_t disp) { 11030f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 11045aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, raw_index, raw_base); 11050f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_index = LowRegisterBits(raw_index); 11060f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 11070f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmSibDisp(entry->skeleton.modrm_opcode, low_base, low_index, scale, disp); 1108b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 1109b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1110b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 1111b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 11120f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitMemReg(const X86EncodingMap* entry, int32_t raw_base, int32_t disp, 11130f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t raw_reg) { 11140f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CheckValidByteRegister(entry, raw_reg); 11155aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, raw_reg, NO_REG, raw_base); 11160f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 11170f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 11180f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmDisp(low_reg, low_base, disp); 1119b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.modrm_opcode); 1120b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 1121b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1122b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 1123b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 11240f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitRegMem(const X86EncodingMap* entry, int32_t raw_reg, int32_t raw_base, 11250f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t disp) { 1126b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers // Opcode will flip operands. 11270f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitMemReg(entry, raw_base, disp, raw_reg); 1128b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 1129b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 11300f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitRegArray(const X86EncodingMap* entry, int32_t raw_reg, int32_t raw_base, 11310f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t raw_index, int scale, int32_t disp) { 11320f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CheckValidByteRegister(entry, raw_reg); 11335aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, raw_reg, raw_index, raw_base); 11340f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 11350f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_index = LowRegisterBits(raw_index); 11360f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 11370f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmSibDisp(low_reg, low_base, low_index, scale, disp); 1138b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.modrm_opcode); 1139b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 1140b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1141b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 1142b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 11430f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitArrayReg(const X86EncodingMap* entry, int32_t raw_base, int32_t raw_index, 11440f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int scale, int32_t disp, int32_t raw_reg) { 1145b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers // Opcode will flip operands. 11460f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitRegArray(entry, raw_reg, raw_base, raw_index, scale, disp); 1147b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers} 1148b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers 11490f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitMemImm(const X86EncodingMap* entry, int32_t raw_base, int32_t disp, 11500f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t imm) { 11510f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 11525aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, NO_REG, raw_base); 11530f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 11540f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmDisp(entry->skeleton.modrm_opcode, low_base, disp); 11552637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0, entry->skeleton.ax_opcode); 11569ed427724a18dc24f9eb2ddf39e4729bea203c2eMark Mendell EmitImm(entry, imm); 11572637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell} 11582637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell 11590f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitArrayImm(const X86EncodingMap* entry, 11600f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t raw_base, int32_t raw_index, int scale, int32_t disp, 11610f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t imm) { 11620f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 11635aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, raw_index, raw_base); 11640f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_index = LowRegisterBits(raw_index); 11650f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 11660f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmSibDisp(entry->skeleton.modrm_opcode, low_base, low_index, scale, disp); 11670f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 11680f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitImm(entry, imm); 11690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers} 11700f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers 11710f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitRegThread(const X86EncodingMap* entry, int32_t raw_reg, int32_t disp) { 11720f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 1173b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_NE(entry->skeleton.prefix1, 0); 11745aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, raw_reg, NO_REG, NO_REG); 11750f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 11760f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmThread(low_reg); 11771fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(disp & 0xFF); 11781fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 8) & 0xFF); 11791fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 16) & 0xFF); 11801fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 24) & 0xFF); 1181b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_EQ(0, entry->skeleton.modrm_opcode); 1182b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 1183b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1184b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers} 1185b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers 11860f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitRegReg(const X86EncodingMap* entry, int32_t raw_reg1, int32_t raw_reg2) { 1187021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu if (!IsByteSecondOperand(entry)) { 1188021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu CheckValidByteRegister(entry, raw_reg1); 1189021b60f31a4443081e63591e184b5d707bba28c1Chao-ying Fu } 11900f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CheckValidByteRegister(entry, raw_reg2); 11915aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, raw_reg1, NO_REG, raw_reg2); 11920f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg1 = LowRegisterBits(raw_reg1); 11930f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg2 = LowRegisterBits(raw_reg2); 11940f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (3 << 6) | (low_reg1 << 3) | low_reg2; 11951fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(modrm); 1196b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.modrm_opcode); 1197b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 1198b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1199b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 1200b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 12010f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitRegRegImm(const X86EncodingMap* entry, int32_t raw_reg1, int32_t raw_reg2, 12020f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t imm) { 12030f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 12045aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, raw_reg1, NO_REG, raw_reg2); 12050f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg1 = LowRegisterBits(raw_reg1); 12060f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg2 = LowRegisterBits(raw_reg2); 12070f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (3 << 6) | (low_reg1 << 3) | low_reg2; 12081fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(modrm); 1209225ae523d1b757d0579e02976446288d0a666a8dElliott Hughes DCHECK_EQ(0, entry->skeleton.modrm_opcode); 1210225ae523d1b757d0579e02976446288d0a666a8dElliott Hughes DCHECK_EQ(0, entry->skeleton.ax_opcode); 1211057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko EmitImm(entry, imm); 1212225ae523d1b757d0579e02976446288d0a666a8dElliott Hughes} 1213225ae523d1b757d0579e02976446288d0a666a8dElliott Hughes 12144708dcd68eebf1173aef1097dad8ab13466059aaMark Mendellvoid X86Mir2Lir::EmitRegMemImm(const X86EncodingMap* entry, 12150f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t raw_reg, int32_t raw_base, int disp, int32_t imm) { 12160f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK(!RegStorage::IsFloat(raw_reg)); 12170f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CheckValidByteRegister(entry, raw_reg); 12185aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, raw_reg, NO_REG, raw_base); 12190f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 12200f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 12210f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmDisp(low_reg, low_base, disp); 12224708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK_EQ(0, entry->skeleton.modrm_opcode); 12234708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell DCHECK_EQ(0, entry->skeleton.ax_opcode); 12244708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell EmitImm(entry, imm); 12254708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell} 12264708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell 12272637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendellvoid X86Mir2Lir::EmitMemRegImm(const X86EncodingMap* entry, 12280f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t raw_base, int32_t disp, int32_t raw_reg, int32_t imm) { 12290f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Opcode will flip operands. 12300f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitRegMemImm(entry, raw_reg, raw_base, disp, imm); 12312637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell} 12322637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell 12330f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitRegImm(const X86EncodingMap* entry, int32_t raw_reg, int32_t imm) { 12340f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CheckValidByteRegister(entry, raw_reg); 12355aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, NO_REG, NO_REG, raw_reg); 12360f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers if (RegStorage::RegNum(raw_reg) == rs_rAX.GetRegNum() && entry->skeleton.ax_opcode != 0) { 12371fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(entry->skeleton.ax_opcode); 1238b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } else { 12390f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 1240057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko EmitOpcode(entry); 12410f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (3 << 6) | (entry->skeleton.modrm_opcode << 3) | low_reg; 12421fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(modrm); 1243b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1244057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko EmitImm(entry, imm); 1245b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers} 1246b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 12470f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitThreadImm(const X86EncodingMap* entry, int32_t disp, int32_t imm) { 12487e399fd3a99ba9c9dbfafdf14f75dd318fa7d454Chao-ying Fu DCHECK_EQ(false, entry->skeleton.r8_form); 12495aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, NO_REG, NO_REG); 12509ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko EmitModrmThread(entry->skeleton.modrm_opcode); 12511fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(disp & 0xFF); 12521fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 8) & 0xFF); 12531fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 16) & 0xFF); 12541fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 24) & 0xFF); 1255057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko EmitImm(entry, imm); 1256b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_EQ(entry->skeleton.ax_opcode, 0); 1257b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers} 1258b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers 12590f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitMovRegImm(const X86EncodingMap* entry, int32_t raw_reg, int64_t imm) { 12600f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 12615aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, NO_REG, NO_REG, raw_reg); 12620f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 12630f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers code_buffer_.push_back(0xB8 + low_reg); 126496992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko switch (entry->skeleton.immediate_bytes) { 126596992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko case 4: 126696992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back(imm & 0xFF); 126796992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 8) & 0xFF); 126896992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 16) & 0xFF); 126996992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 24) & 0xFF); 127096992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko break; 127196992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko case 8: 127296992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back(imm & 0xFF); 127396992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 8) & 0xFF); 127496992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 16) & 0xFF); 127596992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 24) & 0xFF); 127696992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 32) & 0xFF); 127796992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 40) & 0xFF); 127896992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 48) & 0xFF); 127996992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko code_buffer_.push_back((imm >> 56) & 0xFF); 128096992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko break; 128196992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko default: 1282a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko LOG(FATAL) << "Unsupported immediate size for EmitMovRegImm: " 1283a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko << static_cast<uint32_t>(entry->skeleton.immediate_bytes); 128496992e8f2eddba05dc38a15cc7d4e705e8db4022Dmitry Petrochenko } 1285b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers} 1286b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers 12870f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitShiftRegImm(const X86EncodingMap* entry, int32_t raw_reg, int32_t imm) { 12880f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CheckValidByteRegister(entry, raw_reg); 12895aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, NO_REG, NO_REG, raw_reg); 1290b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (imm != 1) { 12911fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(entry->skeleton.opcode); 1292b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 1293b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers // Shorter encoding for 1 bit shift 12941fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(entry->skeleton.ax_opcode); 1295b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 1296057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_NE(0x0F, entry->skeleton.opcode); 1297057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_EQ(0, entry->skeleton.extra_opcode1); 1298057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_EQ(0, entry->skeleton.extra_opcode2); 12990f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 13000f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (3 << 6) | (entry->skeleton.modrm_opcode << 3) | low_reg; 13011fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(modrm); 1302b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (imm != 1) { 1303b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers DCHECK_EQ(entry->skeleton.immediate_bytes, 1); 1304b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers DCHECK(IS_SIMM8(imm)); 13051fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(imm & 0xFF); 1306b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 1307b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers} 1308b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers 13090f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitShiftRegCl(const X86EncodingMap* entry, int32_t raw_reg, int32_t raw_cl) { 13100f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CheckValidByteRegister(entry, raw_reg); 13110f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(rs_rCX.GetRegNum(), RegStorage::RegNum(raw_cl)); 13125aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, NO_REG, NO_REG, raw_reg); 13131fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(entry->skeleton.opcode); 1314057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_NE(0x0F, entry->skeleton.opcode); 13157caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.extra_opcode1); 13167caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.extra_opcode2); 13170f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 13180f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (3 << 6) | (entry->skeleton.modrm_opcode << 3) | low_reg; 13191fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(modrm); 13207caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 13217caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 13227caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers} 13237caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 13240f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitShiftMemCl(const X86EncodingMap* entry, int32_t raw_base, 13250f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t displacement, int32_t raw_cl) { 13260f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 13270f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(rs_rCX.GetRegNum(), RegStorage::RegNum(raw_cl)); 13285aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, NO_REG, NO_REG, raw_base); 1329feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell code_buffer_.push_back(entry->skeleton.opcode); 1330feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_NE(0x0F, entry->skeleton.opcode); 1331feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_EQ(0, entry->skeleton.extra_opcode1); 1332feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_EQ(0, entry->skeleton.extra_opcode2); 13330f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 13340f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmDisp(entry->skeleton.modrm_opcode, low_base, displacement); 1335feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_EQ(0, entry->skeleton.ax_opcode); 1336feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1337feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell} 1338feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell 13390f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitShiftMemImm(const X86EncodingMap* entry, int32_t raw_base, int32_t disp, 13400f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t imm) { 13410f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 13425aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, NO_REG, NO_REG, raw_base); 13432637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell if (imm != 1) { 13442637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell code_buffer_.push_back(entry->skeleton.opcode); 13452637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell } else { 13462637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell // Shorter encoding for 1 bit shift 13472637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell code_buffer_.push_back(entry->skeleton.ax_opcode); 13482637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell } 13492637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_NE(0x0F, entry->skeleton.opcode); 13502637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0, entry->skeleton.extra_opcode1); 13512637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0, entry->skeleton.extra_opcode2); 13520f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 13530f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmDisp(entry->skeleton.modrm_opcode, low_base, disp); 13542637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell if (imm != 1) { 13552637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(entry->skeleton.immediate_bytes, 1); 13562637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK(IS_SIMM8(imm)); 13572637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell code_buffer_.push_back(imm & 0xFF); 13582637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell } 13592637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell} 13602637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell 13610f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitRegCond(const X86EncodingMap* entry, int32_t raw_reg, int32_t cc) { 13620f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers CheckValidByteRegister(entry, raw_reg); 13635aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, NO_REG, NO_REG, raw_reg); 13647caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 13657caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0x0F, entry->skeleton.opcode); 13661fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0x0F); 13677caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0x90, entry->skeleton.extra_opcode1); 13680f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_GE(cc, 0); 13690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_LT(cc, 16); 13700f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers code_buffer_.push_back(0x90 | cc); 13717caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.extra_opcode2); 13720f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 13730f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (3 << 6) | (entry->skeleton.modrm_opcode << 3) | low_reg; 13741fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(modrm); 13757caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(entry->skeleton.immediate_bytes, 0); 13767caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers} 13777caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 13780f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitMemCond(const X86EncodingMap* entry, int32_t raw_base, int32_t disp, 13790f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t cc) { 13800f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 13812637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell if (entry->skeleton.prefix1 != 0) { 13822637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell code_buffer_.push_back(entry->skeleton.prefix1); 13832637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell if (entry->skeleton.prefix2 != 0) { 13842637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell code_buffer_.push_back(entry->skeleton.prefix2); 13852637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell } 13862637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell } else { 13872637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0, entry->skeleton.prefix2); 13882637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell } 13892637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0, entry->skeleton.ax_opcode); 13902637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0x0F, entry->skeleton.opcode); 13912637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell code_buffer_.push_back(0x0F); 13922637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0x90, entry->skeleton.extra_opcode1); 13930f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_GE(cc, 0); 13940f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_LT(cc, 16); 13950f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers code_buffer_.push_back(0x90 | cc); 13962637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0, entry->skeleton.extra_opcode2); 13970f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 13980f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmDisp(entry->skeleton.modrm_opcode, low_base, disp); 13992637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(entry->skeleton.immediate_bytes, 0); 14002637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell} 14012637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell 14020f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitRegRegCond(const X86EncodingMap* entry, int32_t raw_reg1, int32_t raw_reg2, 14030f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t cc) { 14040f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Generate prefix and opcode without the condition. 14050f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 14065aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, raw_reg1, NO_REG, raw_reg2); 1407bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru 1408bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru // Now add the condition. The last byte of opcode is the one that receives it. 14090f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_GE(cc, 0); 14100f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_LT(cc, 16); 14110f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers code_buffer_.back() += cc; 1412bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru 14130f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Not expecting to have to encode immediate or do anything special for ModR/M since there are 14140f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // two registers. 1415bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1416bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru DCHECK_EQ(0, entry->skeleton.modrm_opcode); 1417bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru 1418bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru // For register to register encoding, the mod is 3. 1419bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru const uint8_t mod = (3 << 6); 1420bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru 1421bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru // Encode the ModR/M byte now. 14220f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg1 = LowRegisterBits(raw_reg1); 14230f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg2 = LowRegisterBits(raw_reg2); 14240f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers const uint8_t modrm = mod | (low_reg1 << 3) | low_reg2; 1425bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru code_buffer_.push_back(modrm); 1426bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru} 1427bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru 14280f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitRegMemCond(const X86EncodingMap* entry, int32_t raw_reg1, int32_t raw_base, 14290f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t disp, int32_t cc) { 14300f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Generate prefix and opcode without the condition. 14310f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 14325aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, raw_reg1, NO_REG, raw_base); 14332637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell 14342637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell // Now add the condition. The last byte of opcode is the one that receives it. 14350f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_GE(cc, 0); 14360f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_LT(cc, 16); 14370f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers code_buffer_.back() += cc; 14382637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell 14390f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // Not expecting to have to encode immediate or do anything special for ModR/M since there are 14400f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers // two registers. 14412637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0, entry->skeleton.immediate_bytes); 14422637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell DCHECK_EQ(0, entry->skeleton.modrm_opcode); 14432637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell 14440f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg1 = LowRegisterBits(raw_reg1); 14450f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 14460f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmDisp(low_reg1, low_base, disp); 14472637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell} 14482637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell 14490f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitJmp(const X86EncodingMap* entry, int32_t rel) { 1450b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (entry->opcode == kX86Jmp8) { 1451b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers DCHECK(IS_SIMM8(rel)); 14521fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0xEB); 14531fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(rel & 0xFF); 14547caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } else if (entry->opcode == kX86Jmp32) { 14551fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0xE9); 14561fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(rel & 0xFF); 14571fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((rel >> 8) & 0xFF); 14581fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((rel >> 16) & 0xFF); 14591fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((rel >> 24) & 0xFF); 14604028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell } else if (entry->opcode == kX86Jecxz8) { 14614028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell DCHECK(IS_SIMM8(rel)); 14624028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell code_buffer_.push_back(0xE3); 14634028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell code_buffer_.push_back(rel & 0xFF); 14647caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } else { 14657caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK(entry->opcode == kX86JmpR); 14660f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 14675aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, NO_REG, NO_REG, rel); 1468a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko code_buffer_.push_back(entry->skeleton.opcode); 14690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(rel); 14700f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (3 << 6) | (entry->skeleton.modrm_opcode << 3) | low_reg; 14711fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(modrm); 1472b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers } 1473b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers} 1474b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers 14750f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitJcc(const X86EncodingMap* entry, int32_t rel, int32_t cc) { 14760f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_GE(cc, 0); 1477b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_LT(cc, 16); 1478b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (entry->opcode == kX86Jcc8) { 1479b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers DCHECK(IS_SIMM8(rel)); 14801fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0x70 | cc); 14811fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(rel & 0xFF); 1482b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers } else { 1483b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers DCHECK(entry->opcode == kX86Jcc32); 14841fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0x0F); 14851fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0x80 | cc); 14861fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(rel & 0xFF); 14871fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((rel >> 8) & 0xFF); 14881fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((rel >> 16) & 0xFF); 14891fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((rel >> 24) & 0xFF); 1490b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers } 1491b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers} 1492b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers 14930f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitCallMem(const X86EncodingMap* entry, int32_t raw_base, int32_t disp) { 14940f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 14955aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, NO_REG, raw_base); 14960f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base = LowRegisterBits(raw_base); 14970f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitModrmDisp(entry->skeleton.modrm_opcode, low_base, disp); 1498b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 1499b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1500b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers} 1501b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers 15020f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitCallImmediate(const X86EncodingMap* entry, int32_t disp) { 15030f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 15045aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, NO_REG, NO_REG); 150555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell DCHECK_EQ(4, entry->skeleton.immediate_bytes); 150655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell code_buffer_.push_back(disp & 0xFF); 150755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell code_buffer_.push_back((disp >> 8) & 0xFF); 150855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell code_buffer_.push_back((disp >> 16) & 0xFF); 150955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell code_buffer_.push_back((disp >> 24) & 0xFF); 151055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell DCHECK_EQ(0, entry->skeleton.ax_opcode); 151155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell} 151255d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 15130f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitCallThread(const X86EncodingMap* entry, int32_t disp) { 15140f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 1515b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_NE(entry->skeleton.prefix1, 0); 15165aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefixAndOpcode(entry, NO_REG, NO_REG, NO_REG); 15179ee801f5308aa3c62ae3bedae2658612762ffb91Dmitry Petrochenko EmitModrmThread(entry->skeleton.modrm_opcode); 15181fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(disp & 0xFF); 15191fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 8) & 0xFF); 15201fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 16) & 0xFF); 15211fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 24) & 0xFF); 1522b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 1523b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 1524b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers} 1525b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers 15260f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitPcRel(const X86EncodingMap* entry, int32_t raw_reg, int32_t raw_base_or_table, 15270f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers int32_t raw_index, int scale, int32_t table_or_disp) { 15287caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers int disp; 15297caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers if (entry->opcode == kX86PcRelLoadRA) { 15300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee Mir2Lir::EmbeddedData *tab_rec = 15310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee reinterpret_cast<Mir2Lir::EmbeddedData*>(UnwrapPointer(table_or_disp)); 1532fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee disp = tab_rec->offset; 15337caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } else { 15347caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK(entry->opcode == kX86PcRelAdr); 15350d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee Mir2Lir::EmbeddedData *tab_rec = 15360f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers reinterpret_cast<Mir2Lir::EmbeddedData*>(UnwrapPointer(raw_base_or_table)); 1537fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee disp = tab_rec->offset; 15387caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } 15397caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers if (entry->opcode == kX86PcRelLoadRA) { 15400f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 15415aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, raw_reg, raw_index, raw_base_or_table); 15421fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(entry->skeleton.opcode); 1543057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko DCHECK_NE(0x0F, entry->skeleton.opcode); 15447caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.extra_opcode1); 15457caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.extra_opcode2); 15460f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 15470f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t modrm = (2 << 6) | (low_reg << 3) | rs_rX86_SP.GetRegNum(); 15481fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(modrm); 15497caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_LT(scale, 4); 15500f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_base_or_table = LowRegisterBits(raw_base_or_table); 15510f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_index = LowRegisterBits(raw_index); 15520f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t sib = (scale << 6) | (low_index << 3) | low_base_or_table; 15531fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(sib); 15547caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.immediate_bytes); 15557caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } else { 15560f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 15570f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers code_buffer_.push_back(entry->skeleton.opcode + low_reg); 15587caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } 15591fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(disp & 0xFF); 15601fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 8) & 0xFF); 15611fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 16) & 0xFF); 15621fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back((disp >> 24) & 0xFF); 15637caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.modrm_opcode); 15647caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers DCHECK_EQ(0, entry->skeleton.ax_opcode); 15657caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers} 15667caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 15670f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogersvoid X86Mir2Lir::EmitMacro(const X86EncodingMap* entry, int32_t raw_reg, int32_t offset) { 15680f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(entry->opcode, kX86StartOfMethod) << entry->name; 15690f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers DCHECK_EQ(false, entry->skeleton.r8_form); 15705aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers EmitPrefix(entry, raw_reg, NO_REG, NO_REG); 15711fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0xE8); // call +0 15721fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0); 15731fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0); 15741fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0); 15751fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0); 15767caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 15770f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers uint8_t low_reg = LowRegisterBits(raw_reg); 15780f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers code_buffer_.push_back(0x58 + low_reg); // pop reg 15797caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 1580dd64450b37776f68b9bfc47f8d9a88bc72c95727Elena Sayapina EmitRegImm(&X86Mir2Lir::EncodingMap[cu_->target64 ? kX86Sub64RI : kX86Sub32RI], 15810f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers raw_reg, offset + 5 /* size of call +0 */); 15827caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers} 15837caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers 15841fd3346740dfb7f47be9922312b68a4227fada96buzbeevoid X86Mir2Lir::EmitUnimplemented(const X86EncodingMap* entry, LIR* lir) { 158502031b185b4653e6c72e21f7a51238b903f6d638buzbee UNIMPLEMENTED(WARNING) << "encoding kind for " << entry->name << " " 15861fd3346740dfb7f47be9922312b68a4227fada96buzbee << BuildInsnString(entry->fmt, lir, 0); 15875aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers for (size_t i = 0; i < GetInsnSize(lir); ++i) { 15881fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(0xCC); // push breakpoint instruction - int 3 1589141b0c75986949da0adbf9c07ad92bc675f1bfedIan Rogers } 1590141b0c75986949da0adbf9c07ad92bc675f1bfedIan Rogers} 1591141b0c75986949da0adbf9c07ad92bc675f1bfedIan Rogers 1592e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee/* 1593e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * Assemble the LIR into binary instruction format. Note that we may 1594e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * discover that pc-relative displacements may not fit the selected 1595e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * instruction. In those cases we will try to substitute a new code 1596e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee * sequence or request that the trace be shortened and retried. 1597e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee */ 15980d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeAssemblerStatus X86Mir2Lir::AssembleInstructions(CodeOffset start_addr) { 1599b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers LIR *lir; 1600b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers AssemblerStatus res = kSuccess; // Assume success 1601e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1602141d62275f207bf68c55f583fb206fe586d857cfIan Rogers const bool kVerbosePcFixup = false; 16031fd3346740dfb7f47be9922312b68a4227fada96buzbee for (lir = first_lir_insn_; lir != NULL; lir = NEXT_LIR(lir)) { 1604409fe94ad529d9334587be80b9f6a3d166805508buzbee if (IsPseudoLirOp(lir->opcode)) { 1605b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers continue; 1606b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1607e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1608fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee if (lir->flags.is_nop) { 1609b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers continue; 1610b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1611e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1612b48819db07f9a0992a72173380c24249d7fc648abuzbee if (lir->flags.fixup != kFixupNone) { 1613b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers switch (lir->opcode) { 1614b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers case kX86Jcc8: { 1615fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR *target_lir = lir->target; 1616fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(target_lir != NULL); 1617b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers int delta = 0; 16180d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee CodeOffset pc; 1619b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (IS_SIMM8(lir->operands[0])) { 1620b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers pc = lir->offset + 2 /* opcode + rel8 */; 1621b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 1622b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers pc = lir->offset + 6 /* 2 byte opcode + rel32 */; 1623b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 16240d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee CodeOffset target = target_lir->offset; 1625b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers delta = target - pc; 1626b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (IS_SIMM8(delta) != IS_SIMM8(lir->operands[0])) { 1627c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers if (kVerbosePcFixup) { 1628c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers LOG(INFO) << "Retry for JCC growth at " << lir->offset 1629c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers << " delta: " << delta << " old delta: " << lir->operands[0]; 1630c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers } 1631b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers lir->opcode = kX86Jcc32; 16328dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko lir->flags.size = GetInsnSize(lir); 16338dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(lir->u.m.def_mask->Equals(kEncodeAll)); 16348dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(lir->u.m.use_mask->Equals(kEncodeAll)); 1635b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers res = kRetryAll; 1636b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 16377caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers if (kVerbosePcFixup) { 16387caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers LOG(INFO) << "Source:"; 16391fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpLIRInsn(lir, 0); 16407caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers LOG(INFO) << "Target:"; 16411fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpLIRInsn(target_lir, 0); 16427caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers LOG(INFO) << "Delta " << delta; 16437caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } 16447caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers lir->operands[0] = delta; 16457caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers break; 16467caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } 16477caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers case kX86Jcc32: { 1648fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR *target_lir = lir->target; 1649fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(target_lir != NULL); 16500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee CodeOffset pc = lir->offset + 6 /* 2 byte opcode + rel32 */; 16510d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee CodeOffset target = target_lir->offset; 16527caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers int delta = target - pc; 16537caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers if (kVerbosePcFixup) { 16547caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers LOG(INFO) << "Source:"; 16551fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpLIRInsn(lir, 0); 16567caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers LOG(INFO) << "Target:"; 16571fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpLIRInsn(target_lir, 0); 16587caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers LOG(INFO) << "Delta " << delta; 16597caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } 1660b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers lir->operands[0] = delta; 1661b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers break; 1662b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers } 16634028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell case kX86Jecxz8: { 16644028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell LIR *target_lir = lir->target; 16654028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell DCHECK(target_lir != NULL); 16664028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell CodeOffset pc; 16674028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell pc = lir->offset + 2; // opcode + rel8 16684028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell CodeOffset target = target_lir->offset; 16694028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell int delta = target - pc; 16704028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell lir->operands[0] = delta; 16714028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell DCHECK(IS_SIMM8(delta)); 16724028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell break; 16734028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell } 1674b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers case kX86Jmp8: { 1675fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR *target_lir = lir->target; 1676fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(target_lir != NULL); 1677b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers int delta = 0; 16780d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee CodeOffset pc; 1679b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers if (IS_SIMM8(lir->operands[0])) { 1680b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers pc = lir->offset + 2 /* opcode + rel8 */; 1681b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else { 1682b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers pc = lir->offset + 5 /* opcode + rel32 */; 1683b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 16840d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee CodeOffset target = target_lir->offset; 1685b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers delta = target - pc; 16861fd3346740dfb7f47be9922312b68a4227fada96buzbee if (!(cu_->disable_opt & (1 << kSafeOptimizations)) && delta == 0) { 1687b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers // Useless branch 1688252254b130067cd7a5071865e793966871ae0246buzbee NopLIR(lir); 1689c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers if (kVerbosePcFixup) { 1690c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers LOG(INFO) << "Retry for useless branch at " << lir->offset; 1691c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers } 1692b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers res = kRetryAll; 1693b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } else if (IS_SIMM8(delta) != IS_SIMM8(lir->operands[0])) { 1694c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers if (kVerbosePcFixup) { 1695c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers LOG(INFO) << "Retry for JMP growth at " << lir->offset; 1696c6f3bb87ffbb44d902c4a1f67a71bb108bd01560Ian Rogers } 1697b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers lir->opcode = kX86Jmp32; 16988dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko lir->flags.size = GetInsnSize(lir); 16998dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(lir->u.m.def_mask->Equals(kEncodeAll)); 17008dea81ca9c0201ceaa88086b927a5838a06a3e69Vladimir Marko DCHECK(lir->u.m.use_mask->Equals(kEncodeAll)); 1701b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers res = kRetryAll; 1702b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers } 1703b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers lir->operands[0] = delta; 1704b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers break; 1705b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers } 17067caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers case kX86Jmp32: { 1707fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee LIR *target_lir = lir->target; 1708fa57c47f1b72916371a9c2d5c1389219bce655b4buzbee DCHECK(target_lir != NULL); 17090d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee CodeOffset pc = lir->offset + 5 /* opcode + rel32 */; 17100d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee CodeOffset target = target_lir->offset; 17117caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers int delta = target - pc; 17127caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers lir->operands[0] = delta; 17137caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers break; 17147caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers } 1715b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers default: 171667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (lir->flags.fixup == kFixupLoad) { 171767c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell LIR *target_lir = lir->target; 171867c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell DCHECK(target_lir != NULL); 171967c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell CodeOffset target = target_lir->offset; 172067c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell lir->operands[2] = target; 172167c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell int newSize = GetInsnSize(lir); 172267c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell if (newSize != lir->flags.size) { 172367c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell lir->flags.size = newSize; 172467c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell res = kRetryAll; 172567c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 172667c39c4aefca23cb136157b889c09ee200b3dec6Mark Mendell } 1727b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 1728b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers } 1729b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1730b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers 1731b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers /* 1732b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * If one of the pc-relative instructions expanded we'll have 1733b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * to make another pass. Don't bother to fully assemble the 1734b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers * instruction. 1735b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers */ 1736b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers if (res != kSuccess) { 1737b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers continue; 1738b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 17391fd3346740dfb7f47be9922312b68a4227fada96buzbee CHECK_EQ(static_cast<size_t>(lir->offset), code_buffer_.size()); 17401fd3346740dfb7f47be9922312b68a4227fada96buzbee const X86EncodingMap *entry = &X86Mir2Lir::EncodingMap[lir->opcode]; 17411fd3346740dfb7f47be9922312b68a4227fada96buzbee size_t starting_cbuf_size = code_buffer_.size(); 1742b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes switch (entry->kind) { 1743b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kData: // 4 bytes of data 17441fd3346740dfb7f47be9922312b68a4227fada96buzbee code_buffer_.push_back(lir->operands[0]); 1745b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 17460f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kNullary: // 1 byte of opcode and possible prefixes. 17470f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitNullary(entry); 17484028a6c83a339036864999fdfd2855b012a9f1a7Mark Mendell break; 1749a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko case kRegOpcode: // lir operands - 0: reg 1750a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko EmitOpRegOpcode(entry, lir->operands[0]); 1751a8b4caf7526b6b66a8ae0826bd52c39c66e3c714Vladimir Marko break; 1752b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kReg: // lir operands - 0: reg 17531fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitOpReg(entry, lir->operands[0]); 1754b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 1755b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kMem: // lir operands - 0: base, 1: disp 17561fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitOpMem(entry, lir->operands[0], lir->operands[1]); 1757b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 1758057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko case kArray: // lir operands - 0: base, 1: index, 2: scale, 3: disp 1759057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko EmitOpArray(entry, lir->operands[0], lir->operands[1], lir->operands[2], lir->operands[3]); 1760057c74a3a2d50d1247d4e6472763ca6f59060762Vladimir Marko break; 1761b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kMemReg: // lir operands - 0: base, 1: disp, 2: reg 17621fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitMemReg(entry, lir->operands[0], lir->operands[1], lir->operands[2]); 1763b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 1764343adb52d3f031b6b5e005ff51f9cb04df219b21Mark Mendell case kMemImm: // lir operands - 0: base, 1: disp, 2: immediate 1765343adb52d3f031b6b5e005ff51f9cb04df219b21Mark Mendell EmitMemImm(entry, lir->operands[0], lir->operands[1], lir->operands[2]); 1766343adb52d3f031b6b5e005ff51f9cb04df219b21Mark Mendell break; 17672637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell case kArrayImm: // lir operands - 0: base, 1: index, 2: disp, 3:scale, 4:immediate 17682637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EmitArrayImm(entry, lir->operands[0], lir->operands[1], lir->operands[2], 17692637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell lir->operands[3], lir->operands[4]); 17702637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell break; 1771b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers case kArrayReg: // lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg 17721fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitArrayReg(entry, lir->operands[0], lir->operands[1], lir->operands[2], 1773b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers lir->operands[3], lir->operands[4]); 1774b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers break; 1775b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kRegMem: // lir operands - 0: reg, 1: base, 2: disp 17761fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitRegMem(entry, lir->operands[0], lir->operands[1], lir->operands[2]); 1777b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 1778b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kRegArray: // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp 17791fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitRegArray(entry, lir->operands[0], lir->operands[1], lir->operands[2], 1780b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers lir->operands[3], lir->operands[4]); 1781b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 1782b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers case kRegThread: // lir operands - 0: reg, 1: disp 17831fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitRegThread(entry, lir->operands[0], lir->operands[1]); 1784b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 1785b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kRegReg: // lir operands - 0: reg1, 1: reg2 17861fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitRegReg(entry, lir->operands[0], lir->operands[1]); 1787b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 1788fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao case kRegRegStore: // lir operands - 0: reg2, 1: reg1 17891fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitRegReg(entry, lir->operands[1], lir->operands[0]); 1790fdffdf898f12d91765c7dbe7bcb1ccbbcd2b72d1jeffhao break; 17910f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kMemRegImm: // lir operands - 0: base, 1: disp, 2: reg 3: immediate 17922637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EmitMemRegImm(entry, lir->operands[0], lir->operands[1], lir->operands[2], 17932637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell lir->operands[3]); 17942637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell break; 17950f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kRegRegImm: // lir operands - 0: reg1, 1: reg2, 2: imm 17961fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitRegRegImm(entry, lir->operands[0], lir->operands[1], lir->operands[2]); 1797225ae523d1b757d0579e02976446288d0a666a8dElliott Hughes break; 17980f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kRegRegImmStore: // lir operands - 0: reg2, 1: reg1, 2: imm 17990f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers EmitRegRegImm(entry, lir->operands[1], lir->operands[0], lir->operands[2]); 18000f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers break; 18010f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kRegMemImm: // lir operands - 0: reg, 1: base, 2: disp, 3: imm 18024708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell EmitRegMemImm(entry, lir->operands[0], lir->operands[1], lir->operands[2], 18034708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell lir->operands[3]); 18044708dcd68eebf1173aef1097dad8ab13466059aaMark Mendell break; 1805b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers case kRegImm: // lir operands - 0: reg, 1: immediate 18061fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitRegImm(entry, lir->operands[0], lir->operands[1]); 1807b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 1808b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers case kThreadImm: // lir operands - 0: disp, 1: immediate 18091fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitThreadImm(entry, lir->operands[0], lir->operands[1]); 1810b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 1811b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers case kMovRegImm: // lir operands - 0: reg, 1: immediate 18121fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitMovRegImm(entry, lir->operands[0], lir->operands[1]); 1813b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 18145192cbb12856b12620dc346758605baaa1469cedYixin Shou case kMovRegQuadImm: { 18155192cbb12856b12620dc346758605baaa1469cedYixin Shou int64_t value = static_cast<int64_t>(static_cast<int64_t>(lir->operands[1]) << 32 | 18165192cbb12856b12620dc346758605baaa1469cedYixin Shou static_cast<uint32_t>(lir->operands[2])); 18175192cbb12856b12620dc346758605baaa1469cedYixin Shou EmitMovRegImm(entry, lir->operands[0], value); 18185192cbb12856b12620dc346758605baaa1469cedYixin Shou } 18195192cbb12856b12620dc346758605baaa1469cedYixin Shou break; 1820b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers case kShiftRegImm: // lir operands - 0: reg, 1: immediate 18211fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitShiftRegImm(entry, lir->operands[0], lir->operands[1]); 1822b41b33b5e5f08083e35f84818b4f44d26feb4a8bIan Rogers break; 18232637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell case kShiftMemImm: // lir operands - 0: base, 1: disp, 2:immediate 18242637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EmitShiftMemImm(entry, lir->operands[0], lir->operands[1], lir->operands[2]); 18252637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell break; 18267934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom case kShiftRegCl: // lir operands - 0: reg, 1: cl 18271fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitShiftRegCl(entry, lir->operands[0], lir->operands[1]); 18287caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers break; 1829feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell case kShiftMemCl: // lir operands - 0: base, 1:displacement, 2: cl 1830feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell EmitShiftMemCl(entry, lir->operands[0], lir->operands[1], lir->operands[2]); 1831feb2b4e2d1c6538777bb80b60f3a247537b6221dMark Mendell break; 18327caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers case kRegCond: // lir operands - 0: reg, 1: condition 18331fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitRegCond(entry, lir->operands[0], lir->operands[1]); 18347caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers break; 18352637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell case kMemCond: // lir operands - 0: base, 1: displacement, 2: condition 18362637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell EmitMemCond(entry, lir->operands[0], lir->operands[1], lir->operands[2]); 18372637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell break; 1838bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru case kRegRegCond: // lir operands - 0: reg, 1: reg, 2: condition 1839bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru EmitRegRegCond(entry, lir->operands[0], lir->operands[1], lir->operands[2]); 1840bd288c2c1206bc99fafebfb9120a83f13cf9723bRazvan A Lupusoru break; 18412637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell case kRegMemCond: // lir operands - 0: reg, 1: reg, displacement, 3: condition 1842a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko EmitRegMemCond(entry, lir->operands[0], lir->operands[1], lir->operands[2], 1843a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko lir->operands[3]); 18442637f2e9bf4fc5591994b7c0158afead88321a7cMark Mendell break; 1845b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers case kJmp: // lir operands - 0: rel 184660d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom if (entry->opcode == kX86JmpT) { 184760d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom // This works since the instruction format for jmp and call is basically the same and 184860d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom // EmitCallThread loads opcode info. 184960d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom EmitCallThread(entry, lir->operands[0]); 185060d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom } else { 185160d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom EmitJmp(entry, lir->operands[0]); 185260d7a65f7fb60f502160a2e479e86014c7787553Brian Carlstrom } 1853b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 1854b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers case kJcc: // lir operands - 0: rel, 1: CC, target assigned 18551fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitJcc(entry, lir->operands[0], lir->operands[1]); 1856b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 1857b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers case kCall: 1858b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes switch (entry->opcode) { 185955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell case kX86CallI: // lir operands - 0: disp 186055d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell EmitCallImmediate(entry, lir->operands[0]); 186155d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell break; 1862b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers case kX86CallM: // lir operands - 0: base, 1: disp 18631fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitCallMem(entry, lir->operands[0], lir->operands[1]); 1864b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 1865b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers case kX86CallT: // lir operands - 0: disp 18661fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitCallThread(entry, lir->operands[0]); 1867b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 1868b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers default: 18691fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitUnimplemented(entry, lir); 1870b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 1871b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers } 1872b3ab25b58945f1bd22da1be2eb49dc3eb121011eIan Rogers break; 18737caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers case kPcRel: // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table 18741fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitPcRel(entry, lir->operands[0], lir->operands[1], lir->operands[2], 18757caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers lir->operands[3], lir->operands[4]); 18767caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers break; 1877a20468c004264592f309a548fc71ba62a69b8742Dmitry Petrochenko case kMacro: // lir operands - 0: reg 18781fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitMacro(entry, lir->operands[0], lir->offset); 18797caad77632ae121c9f64c488e3f8f710e2c4813dIan Rogers break; 18800f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kNop: // TODO: these instruction kinds are missing implementations. 18810f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kThreadReg: 18820f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kRegArrayImm: 18830f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kShiftArrayImm: 18840f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kShiftArrayCl: 18850f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kArrayCond: 18860f9b9c508814a62c6e21c6a06cfe4de39b5036c0Ian Rogers case kUnimplemented: 18871fd3346740dfb7f47be9922312b68a4227fada96buzbee EmitUnimplemented(entry, lir); 1888b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers break; 1889e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee } 18905aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers DCHECK_EQ(lir->flags.size, GetInsnSize(lir)); 18915aa6e04061ced68cca8111af1e9c19781b8a9c5dIan Rogers CHECK_EQ(lir->flags.size, code_buffer_.size() - starting_cbuf_size) 18921fd3346740dfb7f47be9922312b68a4227fada96buzbee << "Instruction size mismatch for entry: " << X86Mir2Lir::EncodingMap[lir->opcode].name; 1893b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers } 1894b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers return res; 1895e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} 1896e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee 1897b48819db07f9a0992a72173380c24249d7fc648abuzbee// LIR offset assignment. 1898b48819db07f9a0992a72173380c24249d7fc648abuzbee// TODO: consolidate w/ Arm assembly mechanism. 1899b48819db07f9a0992a72173380c24249d7fc648abuzbeeint X86Mir2Lir::AssignInsnOffsets() { 1900b48819db07f9a0992a72173380c24249d7fc648abuzbee LIR* lir; 1901b48819db07f9a0992a72173380c24249d7fc648abuzbee int offset = 0; 1902b48819db07f9a0992a72173380c24249d7fc648abuzbee 1903b48819db07f9a0992a72173380c24249d7fc648abuzbee for (lir = first_lir_insn_; lir != NULL; lir = NEXT_LIR(lir)) { 1904b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->offset = offset; 1905409fe94ad529d9334587be80b9f6a3d166805508buzbee if (LIKELY(!IsPseudoLirOp(lir->opcode))) { 1906b48819db07f9a0992a72173380c24249d7fc648abuzbee if (!lir->flags.is_nop) { 1907b48819db07f9a0992a72173380c24249d7fc648abuzbee offset += lir->flags.size; 1908b48819db07f9a0992a72173380c24249d7fc648abuzbee } 1909b48819db07f9a0992a72173380c24249d7fc648abuzbee } else if (UNLIKELY(lir->opcode == kPseudoPseudoAlign4)) { 1910b48819db07f9a0992a72173380c24249d7fc648abuzbee if (offset & 0x2) { 1911b48819db07f9a0992a72173380c24249d7fc648abuzbee offset += 2; 1912b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->operands[0] = 1; 1913b48819db07f9a0992a72173380c24249d7fc648abuzbee } else { 1914b48819db07f9a0992a72173380c24249d7fc648abuzbee lir->operands[0] = 0; 1915b48819db07f9a0992a72173380c24249d7fc648abuzbee } 1916b48819db07f9a0992a72173380c24249d7fc648abuzbee } 1917b48819db07f9a0992a72173380c24249d7fc648abuzbee /* Pseudo opcodes don't consume space */ 1918b48819db07f9a0992a72173380c24249d7fc648abuzbee } 1919b48819db07f9a0992a72173380c24249d7fc648abuzbee return offset; 1920b48819db07f9a0992a72173380c24249d7fc648abuzbee} 1921b48819db07f9a0992a72173380c24249d7fc648abuzbee 1922b48819db07f9a0992a72173380c24249d7fc648abuzbee/* 1923b48819db07f9a0992a72173380c24249d7fc648abuzbee * Walk the compilation unit and assign offsets to instructions 1924b48819db07f9a0992a72173380c24249d7fc648abuzbee * and literals and compute the total size of the compiled unit. 1925b48819db07f9a0992a72173380c24249d7fc648abuzbee * TODO: consolidate w/ Arm assembly mechanism. 1926b48819db07f9a0992a72173380c24249d7fc648abuzbee */ 1927b48819db07f9a0992a72173380c24249d7fc648abuzbeevoid X86Mir2Lir::AssignOffsets() { 1928b48819db07f9a0992a72173380c24249d7fc648abuzbee int offset = AssignInsnOffsets(); 1929b48819db07f9a0992a72173380c24249d7fc648abuzbee 1930d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell if (const_vectors_ != nullptr) { 1931d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell /* assign offsets to vector literals */ 1932d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell 1933d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell // First, get offset to 12 mod 16 to align to 16 byte boundary. 1934d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell // This will ensure that the vector is 16 byte aligned, as the procedure is 1935d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell // always aligned at at 4 mod 16. 1936d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell int align_size = (16-4) - (offset & 0xF); 1937d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell if (align_size < 0) { 1938d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell align_size += 16; 1939d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell } 1940d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell 1941d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell offset += align_size; 1942d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell 1943d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell // Now assign each literal the right offset. 1944d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell for (LIR *p = const_vectors_; p != nullptr; p = p->next) { 1945d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell p->offset = offset; 1946d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell offset += 16; 1947d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell } 1948d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell } 1949d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell 1950b48819db07f9a0992a72173380c24249d7fc648abuzbee /* Const values have to be word aligned */ 1951660188264dee3c8f3510e2e24c11816c6b60f197Andreas Gampe offset = RoundUp(offset, 4); 1952b48819db07f9a0992a72173380c24249d7fc648abuzbee 1953b48819db07f9a0992a72173380c24249d7fc648abuzbee /* Set up offsets for literals */ 1954b48819db07f9a0992a72173380c24249d7fc648abuzbee data_offset_ = offset; 1955b48819db07f9a0992a72173380c24249d7fc648abuzbee 1956b48819db07f9a0992a72173380c24249d7fc648abuzbee offset = AssignLiteralOffset(offset); 1957b48819db07f9a0992a72173380c24249d7fc648abuzbee 1958b48819db07f9a0992a72173380c24249d7fc648abuzbee offset = AssignSwitchTablesOffset(offset); 1959b48819db07f9a0992a72173380c24249d7fc648abuzbee 1960b48819db07f9a0992a72173380c24249d7fc648abuzbee offset = AssignFillArrayDataOffset(offset); 1961b48819db07f9a0992a72173380c24249d7fc648abuzbee 1962b48819db07f9a0992a72173380c24249d7fc648abuzbee total_size_ = offset; 1963b48819db07f9a0992a72173380c24249d7fc648abuzbee} 1964b48819db07f9a0992a72173380c24249d7fc648abuzbee 1965b48819db07f9a0992a72173380c24249d7fc648abuzbee/* 1966b48819db07f9a0992a72173380c24249d7fc648abuzbee * Go over each instruction in the list and calculate the offset from the top 1967b48819db07f9a0992a72173380c24249d7fc648abuzbee * before sending them off to the assembler. If out-of-range branch distance is 1968b48819db07f9a0992a72173380c24249d7fc648abuzbee * seen rearrange the instructions a bit to correct it. 1969b48819db07f9a0992a72173380c24249d7fc648abuzbee * TODO: consolidate w/ Arm assembly mechanism. 1970b48819db07f9a0992a72173380c24249d7fc648abuzbee */ 1971b48819db07f9a0992a72173380c24249d7fc648abuzbeevoid X86Mir2Lir::AssembleLIR() { 1972a61f49539a59b610e557b5513695295639496750buzbee cu_->NewTimingSplit("Assemble"); 197355d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 197455d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell // We will remove the method address if we never ended up using it 197555d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell if (store_method_addr_ && !store_method_addr_used_) { 197655d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell setup_method_address_[0]->flags.is_nop = true; 197755d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell setup_method_address_[1]->flags.is_nop = true; 197855d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell } 197955d0eac918321e0525f6e6491f36a80977e0d416Mark Mendell 1980b48819db07f9a0992a72173380c24249d7fc648abuzbee AssignOffsets(); 1981b48819db07f9a0992a72173380c24249d7fc648abuzbee int assembler_retries = 0; 1982b48819db07f9a0992a72173380c24249d7fc648abuzbee /* 1983b48819db07f9a0992a72173380c24249d7fc648abuzbee * Assemble here. Note that we generate code with optimistic assumptions 1984b48819db07f9a0992a72173380c24249d7fc648abuzbee * and if found now to work, we'll have to redo the sequence and retry. 1985b48819db07f9a0992a72173380c24249d7fc648abuzbee */ 1986b48819db07f9a0992a72173380c24249d7fc648abuzbee 1987b48819db07f9a0992a72173380c24249d7fc648abuzbee while (true) { 1988b48819db07f9a0992a72173380c24249d7fc648abuzbee AssemblerStatus res = AssembleInstructions(0); 1989b48819db07f9a0992a72173380c24249d7fc648abuzbee if (res == kSuccess) { 1990b48819db07f9a0992a72173380c24249d7fc648abuzbee break; 1991b48819db07f9a0992a72173380c24249d7fc648abuzbee } else { 1992b48819db07f9a0992a72173380c24249d7fc648abuzbee assembler_retries++; 1993b48819db07f9a0992a72173380c24249d7fc648abuzbee if (assembler_retries > MAX_ASSEMBLER_RETRIES) { 1994b48819db07f9a0992a72173380c24249d7fc648abuzbee CodegenDump(); 1995b48819db07f9a0992a72173380c24249d7fc648abuzbee LOG(FATAL) << "Assembler error - too many retries"; 1996b48819db07f9a0992a72173380c24249d7fc648abuzbee } 1997b48819db07f9a0992a72173380c24249d7fc648abuzbee // Redo offsets and try again 1998b48819db07f9a0992a72173380c24249d7fc648abuzbee AssignOffsets(); 1999b48819db07f9a0992a72173380c24249d7fc648abuzbee code_buffer_.clear(); 2000b48819db07f9a0992a72173380c24249d7fc648abuzbee } 2001b48819db07f9a0992a72173380c24249d7fc648abuzbee } 2002b48819db07f9a0992a72173380c24249d7fc648abuzbee 2003b48819db07f9a0992a72173380c24249d7fc648abuzbee // Install literals 2004b48819db07f9a0992a72173380c24249d7fc648abuzbee InstallLiteralPools(); 2005b48819db07f9a0992a72173380c24249d7fc648abuzbee 2006b48819db07f9a0992a72173380c24249d7fc648abuzbee // Install switch tables 2007b48819db07f9a0992a72173380c24249d7fc648abuzbee InstallSwitchTables(); 2008b48819db07f9a0992a72173380c24249d7fc648abuzbee 2009b48819db07f9a0992a72173380c24249d7fc648abuzbee // Install fill array data 2010b48819db07f9a0992a72173380c24249d7fc648abuzbee InstallFillArrayData(); 2011b48819db07f9a0992a72173380c24249d7fc648abuzbee 2012b48819db07f9a0992a72173380c24249d7fc648abuzbee // Create the mapping table and native offset to reference map. 2013a61f49539a59b610e557b5513695295639496750buzbee cu_->NewTimingSplit("PcMappingTable"); 2014b48819db07f9a0992a72173380c24249d7fc648abuzbee CreateMappingTables(); 2015b48819db07f9a0992a72173380c24249d7fc648abuzbee 2016a61f49539a59b610e557b5513695295639496750buzbee cu_->NewTimingSplit("GcMap"); 2017b48819db07f9a0992a72173380c24249d7fc648abuzbee CreateNativeGcMap(); 2018b48819db07f9a0992a72173380c24249d7fc648abuzbee} 2019b48819db07f9a0992a72173380c24249d7fc648abuzbee 2020e88dfbf138bc204b1ce21911f1c34098ea74af7cbuzbee} // namespace art 2021