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 |