Revision 09aac126 tcg/x86_64/tcg-target.c

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