| OLD | NEW |
| 1 /* | 1 /* |
| 2 * x86 bytecode utility functions | 2 * x86 bytecode utility functions |
| 3 * | 3 * |
| 4 * Copyright (C) 2001-2007 Peter Johnson | 4 * Copyright (C) 2001-2007 Peter Johnson |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| 11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
| 12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
| 13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
| 14 * | 14 * |
| 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' | 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' |
| 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
| 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 25 * POSSIBILITY OF SUCH DAMAGE. | 25 * POSSIBILITY OF SUCH DAMAGE. |
| 26 */ | 26 */ |
| 27 #include <util.h> | 27 #include <util.h> |
| 28 /*@unused@*/ RCSID("$Id: x86bc.c 2130 2008-10-07 05:38:11Z peter $"); | 28 /*@unused@*/ RCSID("$Id: x86bc.c 2279 2010-01-19 07:57:43Z peter $"); |
| 29 | 29 |
| 30 #include <libyasm.h> | 30 #include <libyasm.h> |
| 31 | 31 |
| 32 #include "x86arch.h" | 32 #include "x86arch.h" |
| 33 | 33 |
| 34 | 34 |
| 35 /* Bytecode callback function prototypes */ | 35 /* Bytecode callback function prototypes */ |
| 36 | 36 |
| 37 static void x86_bc_insn_destroy(void *contents); | 37 static void x86_bc_insn_destroy(void *contents); |
| 38 static void x86_bc_insn_print(const void *contents, FILE *f, | 38 static void x86_bc_insn_print(const void *contents, FILE *f, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 x86_bc_jmpfar_print, | 99 x86_bc_jmpfar_print, |
| 100 yasm_bc_finalize_common, | 100 yasm_bc_finalize_common, |
| 101 NULL, | 101 NULL, |
| 102 x86_bc_jmpfar_calc_len, | 102 x86_bc_jmpfar_calc_len, |
| 103 yasm_bc_expand_common, | 103 yasm_bc_expand_common, |
| 104 x86_bc_jmpfar_tobytes, | 104 x86_bc_jmpfar_tobytes, |
| 105 0 | 105 0 |
| 106 }; | 106 }; |
| 107 | 107 |
| 108 int | 108 int |
| 109 yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *drex, | 109 yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3, |
| 110 unsigned char *low3, uintptr_t reg, | 110 uintptr_t reg, unsigned int bits, |
| 111 unsigned int bits, x86_rex_bit_pos rexbit) | 111 x86_rex_bit_pos rexbit) |
| 112 { | 112 { |
| 113 *low3 = (unsigned char)(reg&7); | 113 *low3 = (unsigned char)(reg&7); |
| 114 | 114 |
| 115 if (bits == 64) { | 115 if (bits == 64) { |
| 116 x86_expritem_reg_size size = (x86_expritem_reg_size)(reg & ~0xFUL); | 116 x86_expritem_reg_size size = (x86_expritem_reg_size)(reg & ~0xFUL); |
| 117 | 117 |
| 118 if (size == X86_REG8X || (reg & 0xF) >= 8) { | 118 if (size == X86_REG8X || (reg & 0xF) >= 8) { |
| 119 if (drex) { | 119 /* Check to make sure we can set it */ |
| 120 *drex |= ((reg & 8) >> 3) << rexbit; | 120 if (*rex == 0xff) { |
| 121 } else { | 121 yasm_error_set(YASM_ERROR_TYPE, |
| 122 /* Check to make sure we can set it */ | 122 N_("cannot use A/B/C/DH with instruction needing REX")); |
| 123 if (*rex == 0xff) { | 123 return 1; |
| 124 yasm_error_set(YASM_ERROR_TYPE, | |
| 125 N_("cannot use A/B/C/DH with instruction needing REX")); | |
| 126 return 1; | |
| 127 } | |
| 128 *rex |= 0x40 | (((reg & 8) >> 3) << rexbit); | |
| 129 } | 124 } |
| 125 *rex |= 0x40 | (((reg & 8) >> 3) << rexbit); |
| 130 } else if (size == X86_REG8 && (reg & 7) >= 4) { | 126 } else if (size == X86_REG8 && (reg & 7) >= 4) { |
| 131 /* AH/BH/CH/DH, so no REX allowed */ | 127 /* AH/BH/CH/DH, so no REX allowed */ |
| 132 if (*rex != 0 && *rex != 0xff) { | 128 if (*rex != 0 && *rex != 0xff) { |
| 133 yasm_error_set(YASM_ERROR_TYPE, | 129 yasm_error_set(YASM_ERROR_TYPE, |
| 134 N_("cannot use A/B/C/DH with instruction needing REX")); | 130 N_("cannot use A/B/C/DH with instruction needing REX")); |
| 135 return 1; | 131 return 1; |
| 136 } | 132 } |
| 137 *rex = 0xff; /* Flag so we can NEVER set it (see above) */ | 133 *rex = 0xff; /* Flag so we can NEVER set it (see above) */ |
| 138 } | 134 } |
| 139 } | 135 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 153 yasm_bc_transform(bc, &x86_bc_callback_jmp, jmp); | 149 yasm_bc_transform(bc, &x86_bc_callback_jmp, jmp); |
| 154 } | 150 } |
| 155 | 151 |
| 156 void | 152 void |
| 157 yasm_x86__bc_transform_jmpfar(yasm_bytecode *bc, x86_jmpfar *jmpfar) | 153 yasm_x86__bc_transform_jmpfar(yasm_bytecode *bc, x86_jmpfar *jmpfar) |
| 158 { | 154 { |
| 159 yasm_bc_transform(bc, &x86_bc_callback_jmpfar, jmpfar); | 155 yasm_bc_transform(bc, &x86_bc_callback_jmpfar, jmpfar); |
| 160 } | 156 } |
| 161 | 157 |
| 162 void | 158 void |
| 163 yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare, unsigned int drex, | 159 yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare, |
| 164 unsigned int need_drex, yasm_bytecode *precbc) | 160 yasm_bytecode *precbc) |
| 165 { | 161 { |
| 166 if (yasm_value_finalize(&x86_ea->ea.disp, precbc)) | 162 if (yasm_value_finalize(&x86_ea->ea.disp, precbc)) |
| 167 yasm_error_set(YASM_ERROR_TOO_COMPLEX, | 163 yasm_error_set(YASM_ERROR_TOO_COMPLEX, |
| 168 N_("effective address too complex")); | 164 N_("effective address too complex")); |
| 169 x86_ea->modrm &= 0xC7; /* zero spare/reg bits */ | 165 x86_ea->modrm &= 0xC7; /* zero spare/reg bits */ |
| 170 x86_ea->modrm |= (spare << 3) & 0x38; /* plug in provided bits */ | 166 x86_ea->modrm |= (spare << 3) & 0x38; /* plug in provided bits */ |
| 171 x86_ea->drex = (unsigned char)drex; | |
| 172 x86_ea->need_drex = (unsigned char)need_drex; | |
| 173 } | 167 } |
| 174 | 168 |
| 175 void | 169 void |
| 176 yasm_x86__ea_set_disponly(x86_effaddr *x86_ea) | 170 yasm_x86__ea_set_disponly(x86_effaddr *x86_ea) |
| 177 { | 171 { |
| 178 x86_ea->valid_modrm = 0; | 172 x86_ea->valid_modrm = 0; |
| 179 x86_ea->need_modrm = 0; | 173 x86_ea->need_modrm = 0; |
| 180 x86_ea->valid_sib = 0; | 174 x86_ea->valid_sib = 0; |
| 181 x86_ea->need_sib = 0; | 175 x86_ea->need_sib = 0; |
| 182 x86_ea->need_drex = 0; | |
| 183 } | 176 } |
| 184 | 177 |
| 185 static x86_effaddr * | 178 static x86_effaddr * |
| 186 ea_create(void) | 179 ea_create(void) |
| 187 { | 180 { |
| 188 x86_effaddr *x86_ea = yasm_xmalloc(sizeof(x86_effaddr)); | 181 x86_effaddr *x86_ea = yasm_xmalloc(sizeof(x86_effaddr)); |
| 189 | 182 |
| 190 yasm_value_initialize(&x86_ea->ea.disp, NULL, 0); | 183 yasm_value_initialize(&x86_ea->ea.disp, NULL, 0); |
| 191 x86_ea->ea.need_nonzero_len = 0; | 184 x86_ea->ea.need_nonzero_len = 0; |
| 192 x86_ea->ea.need_disp = 0; | 185 x86_ea->ea.need_disp = 0; |
| 193 x86_ea->ea.nosplit = 0; | 186 x86_ea->ea.nosplit = 0; |
| 194 x86_ea->ea.strong = 0; | 187 x86_ea->ea.strong = 0; |
| 195 x86_ea->ea.segreg = 0; | 188 x86_ea->ea.segreg = 0; |
| 196 x86_ea->ea.pc_rel = 0; | 189 x86_ea->ea.pc_rel = 0; |
| 197 x86_ea->ea.not_pc_rel = 0; | 190 x86_ea->ea.not_pc_rel = 0; |
| 198 x86_ea->ea.data_len = 0; | 191 x86_ea->ea.data_len = 0; |
| 199 x86_ea->modrm = 0; | 192 x86_ea->modrm = 0; |
| 200 x86_ea->valid_modrm = 0; | 193 x86_ea->valid_modrm = 0; |
| 201 x86_ea->need_modrm = 0; | 194 x86_ea->need_modrm = 0; |
| 202 x86_ea->sib = 0; | 195 x86_ea->sib = 0; |
| 203 x86_ea->valid_sib = 0; | 196 x86_ea->valid_sib = 0; |
| 204 x86_ea->need_sib = 0; | 197 x86_ea->need_sib = 0; |
| 205 x86_ea->drex = 0; | |
| 206 x86_ea->need_drex = 0; | |
| 207 | 198 |
| 208 return x86_ea; | 199 return x86_ea; |
| 209 } | 200 } |
| 210 | 201 |
| 211 x86_effaddr * | 202 x86_effaddr * |
| 212 yasm_x86__ea_create_reg(x86_effaddr *x86_ea, unsigned long reg, | 203 yasm_x86__ea_create_reg(x86_effaddr *x86_ea, unsigned long reg, |
| 213 unsigned char *rex, unsigned char *drex, | 204 unsigned char *rex, unsigned int bits) |
| 214 unsigned int bits) | |
| 215 { | 205 { |
| 216 unsigned char rm; | 206 unsigned char rm; |
| 217 | 207 |
| 218 if (yasm_x86__set_rex_from_reg(rex, drex, &rm, reg, bits, X86_REX_B)) | 208 if (yasm_x86__set_rex_from_reg(rex, &rm, reg, bits, X86_REX_B)) |
| 219 return NULL; | 209 return NULL; |
| 220 | 210 |
| 221 if (!x86_ea) | 211 if (!x86_ea) |
| 222 x86_ea = ea_create(); | 212 x86_ea = ea_create(); |
| 223 x86_ea->modrm = 0xC0 | rm; /* Mod=11, R/M=Reg, Reg=0 */ | 213 x86_ea->modrm = 0xC0 | rm; /* Mod=11, R/M=Reg, Reg=0 */ |
| 224 x86_ea->valid_modrm = 1; | 214 x86_ea->valid_modrm = 1; |
| 225 x86_ea->need_modrm = 1; | 215 x86_ea->need_modrm = 1; |
| 226 | 216 |
| 227 return x86_ea; | 217 return x86_ea; |
| 228 } | 218 } |
| 229 | 219 |
| 230 yasm_effaddr * | 220 yasm_effaddr * |
| 231 yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e) | 221 yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e) |
| 232 { | 222 { |
| 233 yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch; | 223 yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch; |
| 234 x86_effaddr *x86_ea; | 224 x86_effaddr *x86_ea; |
| 235 | 225 |
| 236 x86_ea = ea_create(); | 226 x86_ea = ea_create(); |
| 237 | 227 |
| 238 if (arch_x86->parser == X86_PARSER_GAS) { | 228 if (arch_x86->parser == X86_PARSER_GAS) { |
| 239 /* Need to change foo+rip into foo wrt rip. | 229 /* Need to change foo+rip into foo wrt rip (even in .intel_syntax mode). |
| 240 * Note this assumes a particular ordering coming from the parser | 230 * Note this assumes a particular ordering coming from the parser |
| 241 * to work (it's not very smart)! | 231 * to work (it's not very smart)! |
| 242 */ | 232 */ |
| 243 if (e->op == YASM_EXPR_ADD && e->terms[0].type == YASM_EXPR_REG | 233 if (e->op == YASM_EXPR_ADD && e->terms[0].type == YASM_EXPR_REG |
| 244 && e->terms[0].data.reg == X86_RIP) { | 234 && e->terms[0].data.reg == X86_RIP) { |
| 245 /* replace register with 0 */ | 235 /* replace register with 0 */ |
| 246 e->terms[0].type = YASM_EXPR_INT; | 236 e->terms[0].type = YASM_EXPR_INT; |
| 247 e->terms[0].data.intn = yasm_intnum_create_uint(0); | 237 e->terms[0].data.intn = yasm_intnum_create_uint(0); |
| 248 /* build new wrt expression */ | 238 /* build new wrt expression */ |
| 249 e = yasm_expr_create(YASM_EXPR_WRT, yasm_expr_expr(e), | 239 e = yasm_expr_create(YASM_EXPR_WRT, yasm_expr_expr(e), |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 add_span(add_span_data, bc, 1, &x86_ea->ea.disp, -128, 127); | 543 add_span(add_span_data, bc, 1, &x86_ea->ea.disp, -128, 127); |
| 554 } | 544 } |
| 555 bc->len += x86_ea->ea.disp.size/8; | 545 bc->len += x86_ea->ea.disp.size/8; |
| 556 | 546 |
| 557 /* Handle address16 postop case */ | 547 /* Handle address16 postop case */ |
| 558 if (insn->postop == X86_POSTOP_ADDRESS16) | 548 if (insn->postop == X86_POSTOP_ADDRESS16) |
| 559 insn->common.addrsize = 0; | 549 insn->common.addrsize = 0; |
| 560 | 550 |
| 561 /* Compute length of ea and add to total */ | 551 /* Compute length of ea and add to total */ |
| 562 bc->len += x86_ea->need_modrm + (x86_ea->need_sib ? 1:0); | 552 bc->len += x86_ea->need_modrm + (x86_ea->need_sib ? 1:0); |
| 563 bc->len += x86_ea->need_drex ? 1:0; | |
| 564 bc->len += (x86_ea->ea.segreg != 0) ? 1 : 0; | 553 bc->len += (x86_ea->ea.segreg != 0) ? 1 : 0; |
| 565 } | 554 } |
| 566 | 555 |
| 567 if (imm) { | 556 if (imm) { |
| 568 unsigned int immlen = imm->size; | 557 unsigned int immlen = imm->size; |
| 569 | 558 |
| 570 /* TODO: check imm->len vs. sized len from expr? */ | 559 /* TODO: check imm->len vs. sized len from expr? */ |
| 571 | 560 |
| 572 /* Handle signext_imm8 postop special-casing */ | 561 /* Handle signext_imm8 postop special-casing */ |
| 573 if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) { | 562 if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 596 insn->opcode.len = 1; | 585 insn->opcode.len = 1; |
| 597 } | 586 } |
| 598 insn->postop = X86_POSTOP_NONE; | 587 insn->postop = X86_POSTOP_NONE; |
| 599 yasm_intnum_destroy(num); | 588 yasm_intnum_destroy(num); |
| 600 } | 589 } |
| 601 } | 590 } |
| 602 | 591 |
| 603 bc->len += immlen/8; | 592 bc->len += immlen/8; |
| 604 } | 593 } |
| 605 | 594 |
| 606 /* VEX prefixes never have REX. We can come into this function with the | 595 /* VEX and XOP prefixes never have REX (it's embedded in the opcode). |
| 607 * three byte form, so we need to see if we can optimize to the two byte | 596 * For VEX, we can come into this function with the three byte form, |
| 608 * form. We can't do it earlier, as we don't know all of the REX byte | 597 * so we need to see if we can optimize to the two byte form. |
| 609 * until now. | 598 * We can't do it earlier, as we don't know all of the REX byte until now. |
| 610 */ | 599 */ |
| 611 if (insn->special_prefix == 0xC4) { | 600 if (insn->special_prefix == 0xC4) { |
| 612 /* See if we can shorten the VEX prefix to its two byte form. | 601 /* See if we can shorten the VEX prefix to its two byte form. |
| 613 * In order to do this, REX.X, REX.B, and REX.W/VEX.W must all be 0, | 602 * In order to do this, REX.X, REX.B, and REX.W/VEX.W must all be 0, |
| 614 * and the VEX mmmmm field must be 1. | 603 * and the VEX mmmmm field must be 1. |
| 615 */ | 604 */ |
| 616 if ((insn->opcode.opcode[0] & 0x1F) == 1 && | 605 if ((insn->opcode.opcode[0] & 0x1F) == 1 && |
| 617 (insn->opcode.opcode[1] & 0x80) == 0 && | 606 (insn->opcode.opcode[1] & 0x80) == 0 && |
| 618 (insn->rex == 0xff || (insn->rex & 0x0B) == 0)) { | 607 (insn->rex == 0xff || (insn->rex & 0x0B) == 0)) { |
| 619 insn->opcode.opcode[0] = insn->opcode.opcode[1]; | 608 insn->opcode.opcode[0] = insn->opcode.opcode[1]; |
| 620 insn->opcode.opcode[1] = insn->opcode.opcode[2]; | 609 insn->opcode.opcode[1] = insn->opcode.opcode[2]; |
| 621 insn->opcode.opcode[2] = 0; /* sanity */ | 610 insn->opcode.opcode[2] = 0; /* sanity */ |
| 622 insn->opcode.len = 2; | 611 insn->opcode.len = 2; |
| 623 insn->special_prefix = 0xC5; /* mark as two-byte VEX */ | 612 insn->special_prefix = 0xC5; /* mark as two-byte VEX */ |
| 624 } | 613 } |
| 625 } else if (insn->rex != 0xff && insn->rex != 0 && | 614 } else if (insn->rex != 0xff && insn->rex != 0 && |
| 626 insn->special_prefix != 0xC5) | 615 insn->special_prefix != 0xC5 && insn->special_prefix != 0x8F) |
| 627 bc->len++; | 616 bc->len++; |
| 628 | 617 |
| 629 bc->len += insn->opcode.len; | 618 bc->len += insn->opcode.len; |
| 630 bc->len += x86_common_calc_len(&insn->common); | 619 bc->len += x86_common_calc_len(&insn->common); |
| 631 bc->len += (insn->special_prefix != 0) ? 1:0; | 620 bc->len += (insn->special_prefix != 0) ? 1:0; |
| 632 return 0; | 621 return 0; |
| 633 } | 622 } |
| 634 | 623 |
| 635 static int | 624 static int |
| 636 x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val, | 625 x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val, |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 x86_insn *insn = (x86_insn *)bc->contents; | 807 x86_insn *insn = (x86_insn *)bc->contents; |
| 819 /*@null@*/ x86_effaddr *x86_ea = (x86_effaddr *)insn->x86_ea; | 808 /*@null@*/ x86_effaddr *x86_ea = (x86_effaddr *)insn->x86_ea; |
| 820 yasm_value *imm = insn->imm; | 809 yasm_value *imm = insn->imm; |
| 821 unsigned char *bufp_orig = *bufp; | 810 unsigned char *bufp_orig = *bufp; |
| 822 | 811 |
| 823 /* Prefixes */ | 812 /* Prefixes */ |
| 824 x86_common_tobytes(&insn->common, bufp, | 813 x86_common_tobytes(&insn->common, bufp, |
| 825 x86_ea ? (unsigned int)(x86_ea->ea.segreg>>8) : 0); | 814 x86_ea ? (unsigned int)(x86_ea->ea.segreg>>8) : 0); |
| 826 if (insn->special_prefix != 0) | 815 if (insn->special_prefix != 0) |
| 827 YASM_WRITE_8(*bufp, insn->special_prefix); | 816 YASM_WRITE_8(*bufp, insn->special_prefix); |
| 828 if (insn->special_prefix == 0xC4) { | 817 if (insn->special_prefix == 0xC4 || insn->special_prefix == 0x8F) { |
| 829 /* 3-byte VEX; merge in 1s complement of REX.R, REX.X, REX.B */ | 818 /* 3-byte VEX/XOP; merge in 1s complement of REX.R, REX.X, REX.B */ |
| 830 insn->opcode.opcode[0] &= 0x1F; | 819 insn->opcode.opcode[0] &= 0x1F; |
| 831 if (insn->rex != 0xff) | 820 if (insn->rex != 0xff) |
| 832 insn->opcode.opcode[0] |= ((~insn->rex) & 0x07) << 5; | 821 insn->opcode.opcode[0] |= ((~insn->rex) & 0x07) << 5; |
| 833 /* merge REX.W via ORing; there should never be a case in which REX.W | 822 /* merge REX.W via ORing; there should never be a case in which REX.W |
| 834 * is important when VEX.W is already set by the instruction. | 823 * is important when VEX.W is already set by the instruction. |
| 835 */ | 824 */ |
| 836 if (insn->rex != 0xff && (insn->rex & 0x8) != 0) | 825 if (insn->rex != 0xff && (insn->rex & 0x8) != 0) |
| 837 insn->opcode.opcode[1] |= 0x80; | 826 insn->opcode.opcode[1] |= 0x80; |
| 838 } else if (insn->special_prefix == 0xC5) { | 827 } else if (insn->special_prefix == 0xC5) { |
| 839 /* 2-byte VEX; merge in 1s complement of REX.R */ | 828 /* 2-byte VEX; merge in 1s complement of REX.R */ |
| (...skipping 21 matching lines...) Expand all Loading... |
| 861 yasm_internal_error(N_("invalid Mod/RM in x86 tobytes_insn")); | 850 yasm_internal_error(N_("invalid Mod/RM in x86 tobytes_insn")); |
| 862 YASM_WRITE_8(*bufp, x86_ea->modrm); | 851 YASM_WRITE_8(*bufp, x86_ea->modrm); |
| 863 } | 852 } |
| 864 | 853 |
| 865 if (x86_ea->need_sib) { | 854 if (x86_ea->need_sib) { |
| 866 if (!x86_ea->valid_sib) | 855 if (!x86_ea->valid_sib) |
| 867 yasm_internal_error(N_("invalid SIB in x86 tobytes_insn")); | 856 yasm_internal_error(N_("invalid SIB in x86 tobytes_insn")); |
| 868 YASM_WRITE_8(*bufp, x86_ea->sib); | 857 YASM_WRITE_8(*bufp, x86_ea->sib); |
| 869 } | 858 } |
| 870 | 859 |
| 871 if (x86_ea->need_drex) | |
| 872 YASM_WRITE_8(*bufp, x86_ea->drex); | |
| 873 | |
| 874 if (x86_ea->ea.need_disp) { | 860 if (x86_ea->ea.need_disp) { |
| 875 unsigned int disp_len = x86_ea->ea.disp.size/8; | 861 unsigned int disp_len = x86_ea->ea.disp.size/8; |
| 876 | 862 |
| 877 if (x86_ea->ea.disp.ip_rel) { | 863 if (x86_ea->ea.disp.ip_rel) { |
| 878 /* Adjust relative displacement to end of bytecode */ | 864 /* Adjust relative displacement to end of bytecode */ |
| 879 /*@only@*/ yasm_intnum *delta; | 865 /*@only@*/ yasm_intnum *delta; |
| 880 delta = yasm_intnum_create_int(-(long)bc->len); | 866 delta = yasm_intnum_create_int(-(long)bc->len); |
| 881 if (!x86_ea->ea.disp.abs) | 867 if (!x86_ea->ea.disp.abs) |
| 882 x86_ea->ea.disp.abs = | 868 x86_ea->ea.disp.abs = |
| 883 yasm_expr_create_ident(yasm_expr_int(delta), bc->line); | 869 yasm_expr_create_ident(yasm_expr_int(delta), bc->line); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1037 | 1023 |
| 1038 int | 1024 int |
| 1039 yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn, | 1025 yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn, |
| 1040 unsigned char *buf, size_t destsize, size_t valsize, | 1026 unsigned char *buf, size_t destsize, size_t valsize, |
| 1041 int shift, const yasm_bytecode *bc, int warn) | 1027 int shift, const yasm_bytecode *bc, int warn) |
| 1042 { | 1028 { |
| 1043 /* Write value out. */ | 1029 /* Write value out. */ |
| 1044 yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn); | 1030 yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn); |
| 1045 return 0; | 1031 return 0; |
| 1046 } | 1032 } |
| OLD | NEW |