Revision 09aac126
b/tcg/x86_64/tcg-target.c | ||
---|---|---|
217 | 217 |
#define JCC_JLE 0xe |
218 | 218 |
#define JCC_JG 0xf |
219 | 219 |
|
220 |
#define P_EXT 0x100 /* 0x0f opcode prefix */ |
|
221 |
#define P_REXW 0x200 /* set rex.w = 1 */ |
|
222 |
#define P_REXB 0x400 /* force rex use for byte registers */ |
|
220 |
#define P_EXT 0x100 /* 0x0f opcode prefix */ |
|
221 |
#define P_REXW 0x200 /* set rex.w = 1 */ |
|
222 |
#define P_REXB_R 0x400 /* REG field as byte register */ |
|
223 |
#define P_REXB_RM 0x800 /* R/M field as byte register */ |
|
223 | 224 |
|
224 | 225 |
static const uint8_t tcg_cond_to_jcc[10] = { |
225 | 226 |
[TCG_COND_EQ] = JCC_JE, |
... | ... | |
234 | 235 |
[TCG_COND_GTU] = JCC_JA, |
235 | 236 |
}; |
236 | 237 |
|
237 |
static inline void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
|
|
238 |
static void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x) |
|
238 | 239 |
{ |
239 |
int rex; |
|
240 |
rex = ((opc >> 6) & 0x8) | ((r >> 1) & 0x4) | |
|
241 |
((x >> 2) & 2) | ((rm >> 3) & 1); |
|
242 |
if (rex || (opc & P_REXB)) { |
|
243 |
tcg_out8(s, rex | 0x40); |
|
240 |
int rex = 0; |
|
241 |
|
|
242 |
rex |= (opc & P_REXW) >> 6; /* REX.W */ |
|
243 |
rex |= (r & 8) >> 1; /* REX.R */ |
|
244 |
rex |= (x & 8) >> 2; /* REX.X */ |
|
245 |
rex |= (rm & 8) >> 3; /* REX.B */ |
|
246 |
|
|
247 |
/* P_REXB_{R,RM} indicates that the given register is the low byte. |
|
248 |
For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do, |
|
249 |
as otherwise the encoding indicates %[abcd]h. Note that the values |
|
250 |
that are ORed in merely indicate that the REX byte must be present; |
|
251 |
those bits get discarded in output. */ |
|
252 |
rex |= opc & (r >= 4 ? P_REXB_R : 0); |
|
253 |
rex |= opc & (rm >= 4 ? P_REXB_RM : 0); |
|
254 |
|
|
255 |
if (rex) { |
|
256 |
tcg_out8(s, (uint8_t)(rex | 0x40)); |
|
244 | 257 |
} |
245 |
if (opc & P_EXT) |
|
258 |
if (opc & P_EXT) {
|
|
246 | 259 |
tcg_out8(s, 0x0f); |
260 |
} |
|
247 | 261 |
tcg_out8(s, opc & 0xff); |
248 | 262 |
} |
249 | 263 |
|
... | ... | |
408 | 422 |
tcg_out8(s, val); |
409 | 423 |
} else if (c == ARITH_AND && val == 0xffu) { |
410 | 424 |
/* movzbl */ |
411 |
tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, r0, r0); |
|
425 |
tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB_RM, r0, r0);
|
|
412 | 426 |
} else if (c == ARITH_AND && val == 0xffffu) { |
413 | 427 |
/* movzwl */ |
414 | 428 |
tcg_out_modrm(s, 0xb7 | P_EXT, r0, r0); |
... | ... | |
776 | 790 |
switch(opc) { |
777 | 791 |
case 0: |
778 | 792 |
/* movzbl */ |
779 |
tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, TCG_REG_RSI, data_reg); |
|
793 |
tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB_RM, TCG_REG_RSI, data_reg);
|
|
780 | 794 |
break; |
781 | 795 |
case 1: |
782 | 796 |
/* movzwl */ |
... | ... | |
829 | 843 |
switch(opc) { |
830 | 844 |
case 0: |
831 | 845 |
/* movb */ |
832 |
tcg_out_modrm_offset(s, 0x88 | P_REXB, data_reg, r0, offset); |
|
846 |
tcg_out_modrm_offset(s, 0x88 | P_REXB_R, data_reg, r0, offset);
|
|
833 | 847 |
break; |
834 | 848 |
case 1: |
835 | 849 |
if (bswap) { |
... | ... | |
964 | 978 |
case INDEX_op_st8_i32: |
965 | 979 |
case INDEX_op_st8_i64: |
966 | 980 |
/* movb */ |
967 |
tcg_out_modrm_offset(s, 0x88 | P_REXB, args[0], args[1], args[2]); |
|
981 |
tcg_out_modrm_offset(s, 0x88 | P_REXB_R, args[0], args[1], args[2]);
|
|
968 | 982 |
break; |
969 | 983 |
case INDEX_op_st16_i32: |
970 | 984 |
case INDEX_op_st16_i64: |
... | ... | |
1161 | 1175 |
break; |
1162 | 1176 |
|
1163 | 1177 |
case INDEX_op_ext8s_i32: |
1164 |
tcg_out_modrm(s, 0xbe | P_EXT | P_REXB, args[0], args[1]); |
|
1178 |
tcg_out_modrm(s, 0xbe | P_EXT | P_REXB_RM, args[0], args[1]);
|
|
1165 | 1179 |
break; |
1166 | 1180 |
case INDEX_op_ext16s_i32: |
1167 | 1181 |
tcg_out_modrm(s, 0xbf | P_EXT, args[0], args[1]); |
... | ... | |
1177 | 1191 |
break; |
1178 | 1192 |
case INDEX_op_ext8u_i32: |
1179 | 1193 |
case INDEX_op_ext8u_i64: |
1180 |
tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB, args[0], args[1]); |
|
1194 |
tcg_out_modrm(s, 0xb6 | P_EXT | P_REXB_RM, args[0], args[1]);
|
|
1181 | 1195 |
break; |
1182 | 1196 |
case INDEX_op_ext16u_i32: |
1183 | 1197 |
case INDEX_op_ext16u_i64: |
Also available in: Unified diff