Annotation of qemu/tcg/i386/tcg-target.c, revision 1.1.1.7

1.1       root        1: /*
                      2:  * Tiny Code Generator for QEMU
                      3:  *
                      4:  * Copyright (c) 2008 Fabrice Bellard
                      5:  *
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: 
                     25: #ifndef NDEBUG
                     26: static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
1.1.1.4   root       27: #if TCG_TARGET_REG_BITS == 64
                     28:     "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
                     29:     "%r8",  "%r9",  "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
                     30: #else
                     31:     "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
                     32: #endif
1.1       root       33: };
                     34: #endif
                     35: 
                     36: static const int tcg_target_reg_alloc_order[] = {
1.1.1.4   root       37: #if TCG_TARGET_REG_BITS == 64
                     38:     TCG_REG_RBP,
                     39:     TCG_REG_RBX,
                     40:     TCG_REG_R12,
                     41:     TCG_REG_R13,
                     42:     TCG_REG_R14,
                     43:     TCG_REG_R15,
                     44:     TCG_REG_R10,
                     45:     TCG_REG_R11,
                     46:     TCG_REG_R9,
                     47:     TCG_REG_R8,
                     48:     TCG_REG_RCX,
                     49:     TCG_REG_RDX,
                     50:     TCG_REG_RSI,
                     51:     TCG_REG_RDI,
                     52:     TCG_REG_RAX,
                     53: #else
1.1       root       54:     TCG_REG_EBX,
                     55:     TCG_REG_ESI,
                     56:     TCG_REG_EDI,
                     57:     TCG_REG_EBP,
1.1.1.4   root       58:     TCG_REG_ECX,
                     59:     TCG_REG_EDX,
                     60:     TCG_REG_EAX,
                     61: #endif
1.1       root       62: };
                     63: 
1.1.1.4   root       64: static const int tcg_target_call_iarg_regs[] = {
                     65: #if TCG_TARGET_REG_BITS == 64
1.1.1.7 ! root       66: #if defined(_WIN64)
        !            67:     TCG_REG_RCX,
        !            68:     TCG_REG_RDX,
        !            69: #else
1.1.1.4   root       70:     TCG_REG_RDI,
                     71:     TCG_REG_RSI,
                     72:     TCG_REG_RDX,
                     73:     TCG_REG_RCX,
1.1.1.7 ! root       74: #endif
1.1.1.4   root       75:     TCG_REG_R8,
                     76:     TCG_REG_R9,
                     77: #else
                     78:     TCG_REG_EAX,
                     79:     TCG_REG_EDX,
                     80:     TCG_REG_ECX
                     81: #endif
                     82: };
                     83: 
1.1.1.6   root       84: static const int tcg_target_call_oarg_regs[] = {
1.1.1.4   root       85:     TCG_REG_EAX,
1.1.1.6   root       86: #if TCG_TARGET_REG_BITS == 32
1.1.1.4   root       87:     TCG_REG_EDX
1.1.1.6   root       88: #endif
1.1.1.4   root       89: };
1.1       root       90: 
                     91: static uint8_t *tb_ret_addr;
                     92: 
1.1.1.4   root       93: static void patch_reloc(uint8_t *code_ptr, int type,
1.1       root       94:                         tcg_target_long value, tcg_target_long addend)
                     95: {
                     96:     value += addend;
                     97:     switch(type) {
1.1.1.4   root       98:     case R_386_PC32:
                     99:         value -= (uintptr_t)code_ptr;
                    100:         if (value != (int32_t)value) {
                    101:             tcg_abort();
                    102:         }
1.1       root      103:         *(uint32_t *)code_ptr = value;
                    104:         break;
1.1.1.4   root      105:     case R_386_PC8:
                    106:         value -= (uintptr_t)code_ptr;
                    107:         if (value != (int8_t)value) {
                    108:             tcg_abort();
                    109:         }
                    110:         *(uint8_t *)code_ptr = value;
1.1       root      111:         break;
                    112:     default:
                    113:         tcg_abort();
                    114:     }
                    115: }
                    116: 
                    117: /* maximum number of register used for input function arguments */
                    118: static inline int tcg_target_get_call_iarg_regs_count(int flags)
                    119: {
1.1.1.4   root      120:     if (TCG_TARGET_REG_BITS == 64) {
                    121:         return 6;
                    122:     }
                    123: 
1.1.1.7 ! root      124:     return 0;
1.1       root      125: }
                    126: 
                    127: /* parse target specific constraints */
                    128: static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
                    129: {
                    130:     const char *ct_str;
                    131: 
                    132:     ct_str = *pct_str;
                    133:     switch(ct_str[0]) {
                    134:     case 'a':
                    135:         ct->ct |= TCG_CT_REG;
                    136:         tcg_regset_set_reg(ct->u.regs, TCG_REG_EAX);
                    137:         break;
                    138:     case 'b':
                    139:         ct->ct |= TCG_CT_REG;
                    140:         tcg_regset_set_reg(ct->u.regs, TCG_REG_EBX);
                    141:         break;
                    142:     case 'c':
                    143:         ct->ct |= TCG_CT_REG;
                    144:         tcg_regset_set_reg(ct->u.regs, TCG_REG_ECX);
                    145:         break;
                    146:     case 'd':
                    147:         ct->ct |= TCG_CT_REG;
                    148:         tcg_regset_set_reg(ct->u.regs, TCG_REG_EDX);
                    149:         break;
                    150:     case 'S':
                    151:         ct->ct |= TCG_CT_REG;
                    152:         tcg_regset_set_reg(ct->u.regs, TCG_REG_ESI);
                    153:         break;
                    154:     case 'D':
                    155:         ct->ct |= TCG_CT_REG;
                    156:         tcg_regset_set_reg(ct->u.regs, TCG_REG_EDI);
                    157:         break;
                    158:     case 'q':
                    159:         ct->ct |= TCG_CT_REG;
1.1.1.4   root      160:         if (TCG_TARGET_REG_BITS == 64) {
                    161:             tcg_regset_set32(ct->u.regs, 0, 0xffff);
                    162:         } else {
                    163:             tcg_regset_set32(ct->u.regs, 0, 0xf);
                    164:         }
1.1       root      165:         break;
1.1.1.6   root      166:     case 'Q':
                    167:         ct->ct |= TCG_CT_REG;
                    168:         tcg_regset_set32(ct->u.regs, 0, 0xf);
                    169:         break;
1.1       root      170:     case 'r':
                    171:         ct->ct |= TCG_CT_REG;
1.1.1.4   root      172:         if (TCG_TARGET_REG_BITS == 64) {
                    173:             tcg_regset_set32(ct->u.regs, 0, 0xffff);
                    174:         } else {
                    175:             tcg_regset_set32(ct->u.regs, 0, 0xff);
                    176:         }
1.1       root      177:         break;
                    178: 
                    179:         /* qemu_ld/st address constraint */
                    180:     case 'L':
                    181:         ct->ct |= TCG_CT_REG;
1.1.1.4   root      182:         if (TCG_TARGET_REG_BITS == 64) {
                    183:             tcg_regset_set32(ct->u.regs, 0, 0xffff);
1.1.1.7 ! root      184:             tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[0]);
        !           185:             tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[1]);
        !           186: #ifdef CONFIG_TCG_PASS_AREG0
        !           187:             tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[2]);
        !           188: #endif
1.1.1.4   root      189:         } else {
                    190:             tcg_regset_set32(ct->u.regs, 0, 0xff);
                    191:             tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
                    192:             tcg_regset_reset_reg(ct->u.regs, TCG_REG_EDX);
                    193:         }
                    194:         break;
                    195: 
                    196:     case 'e':
                    197:         ct->ct |= TCG_CT_CONST_S32;
                    198:         break;
                    199:     case 'Z':
                    200:         ct->ct |= TCG_CT_CONST_U32;
1.1       root      201:         break;
1.1.1.4   root      202: 
1.1       root      203:     default:
                    204:         return -1;
                    205:     }
                    206:     ct_str++;
                    207:     *pct_str = ct_str;
                    208:     return 0;
                    209: }
                    210: 
                    211: /* test if a constant matches the constraint */
                    212: static inline int tcg_target_const_match(tcg_target_long val,
                    213:                                          const TCGArgConstraint *arg_ct)
                    214: {
1.1.1.4   root      215:     int ct = arg_ct->ct;
                    216:     if (ct & TCG_CT_CONST) {
1.1       root      217:         return 1;
1.1.1.4   root      218:     }
                    219:     if ((ct & TCG_CT_CONST_S32) && val == (int32_t)val) {
                    220:         return 1;
                    221:     }
                    222:     if ((ct & TCG_CT_CONST_U32) && val == (uint32_t)val) {
                    223:         return 1;
                    224:     }
                    225:     return 0;
1.1       root      226: }
                    227: 
1.1.1.4   root      228: #if TCG_TARGET_REG_BITS == 64
                    229: # define LOWREGMASK(x) ((x) & 7)
                    230: #else
                    231: # define LOWREGMASK(x) (x)
                    232: #endif
                    233: 
                    234: #define P_EXT          0x100           /* 0x0f opcode prefix */
                    235: #define P_DATA16       0x200           /* 0x66 opcode prefix */
                    236: #if TCG_TARGET_REG_BITS == 64
                    237: # define P_ADDR32      0x400           /* 0x67 opcode prefix */
                    238: # define P_REXW                0x800           /* Set REX.W = 1 */
                    239: # define P_REXB_R      0x1000          /* REG field as byte register */
                    240: # define P_REXB_RM     0x2000          /* R/M field as byte register */
                    241: #else
                    242: # define P_ADDR32      0
                    243: # define P_REXW                0
                    244: # define P_REXB_R      0
                    245: # define P_REXB_RM     0
                    246: #endif
                    247: 
                    248: #define OPC_ARITH_EvIz (0x81)
                    249: #define OPC_ARITH_EvIb (0x83)
                    250: #define OPC_ARITH_GvEv (0x03)          /* ... plus (ARITH_FOO << 3) */
                    251: #define OPC_ADD_GvEv   (OPC_ARITH_GvEv | (ARITH_ADD << 3))
                    252: #define OPC_BSWAP      (0xc8 | P_EXT)
                    253: #define OPC_CALL_Jz    (0xe8)
                    254: #define OPC_CMP_GvEv   (OPC_ARITH_GvEv | (ARITH_CMP << 3))
                    255: #define OPC_DEC_r32    (0x48)
                    256: #define OPC_IMUL_GvEv  (0xaf | P_EXT)
                    257: #define OPC_IMUL_GvEvIb        (0x6b)
                    258: #define OPC_IMUL_GvEvIz        (0x69)
                    259: #define OPC_INC_r32    (0x40)
                    260: #define OPC_JCC_long   (0x80 | P_EXT)  /* ... plus condition code */
                    261: #define OPC_JCC_short  (0x70)          /* ... plus condition code */
                    262: #define OPC_JMP_long   (0xe9)
                    263: #define OPC_JMP_short  (0xeb)
                    264: #define OPC_LEA         (0x8d)
                    265: #define OPC_MOVB_EvGv  (0x88)          /* stores, more or less */
                    266: #define OPC_MOVL_EvGv  (0x89)          /* stores, more or less */
                    267: #define OPC_MOVL_GvEv  (0x8b)          /* loads, more or less */
                    268: #define OPC_MOVL_EvIz  (0xc7)
                    269: #define OPC_MOVL_Iv     (0xb8)
                    270: #define OPC_MOVSBL     (0xbe | P_EXT)
                    271: #define OPC_MOVSWL     (0xbf | P_EXT)
                    272: #define OPC_MOVSLQ     (0x63 | P_REXW)
                    273: #define OPC_MOVZBL     (0xb6 | P_EXT)
                    274: #define OPC_MOVZWL     (0xb7 | P_EXT)
                    275: #define OPC_POP_r32    (0x58)
                    276: #define OPC_PUSH_r32   (0x50)
                    277: #define OPC_PUSH_Iv    (0x68)
                    278: #define OPC_PUSH_Ib    (0x6a)
                    279: #define OPC_RET                (0xc3)
                    280: #define OPC_SETCC      (0x90 | P_EXT | P_REXB_RM) /* ... plus cc */
                    281: #define OPC_SHIFT_1    (0xd1)
                    282: #define OPC_SHIFT_Ib   (0xc1)
                    283: #define OPC_SHIFT_cl   (0xd3)
                    284: #define OPC_TESTL      (0x85)
                    285: #define OPC_XCHG_ax_r32        (0x90)
                    286: 
                    287: #define OPC_GRP3_Ev    (0xf7)
                    288: #define OPC_GRP5       (0xff)
                    289: 
                    290: /* Group 1 opcode extensions for 0x80-0x83.
                    291:    These are also used as modifiers for OPC_ARITH.  */
1.1       root      292: #define ARITH_ADD 0
                    293: #define ARITH_OR  1
                    294: #define ARITH_ADC 2
                    295: #define ARITH_SBB 3
                    296: #define ARITH_AND 4
                    297: #define ARITH_SUB 5
                    298: #define ARITH_XOR 6
                    299: #define ARITH_CMP 7
                    300: 
1.1.1.4   root      301: /* Group 2 opcode extensions for 0xc0, 0xc1, 0xd0-0xd3.  */
1.1.1.2   root      302: #define SHIFT_ROL 0
                    303: #define SHIFT_ROR 1
1.1       root      304: #define SHIFT_SHL 4
                    305: #define SHIFT_SHR 5
                    306: #define SHIFT_SAR 7
                    307: 
1.1.1.4   root      308: /* Group 3 opcode extensions for 0xf6, 0xf7.  To be used with OPC_GRP3.  */
                    309: #define EXT3_NOT   2
                    310: #define EXT3_NEG   3
                    311: #define EXT3_MUL   4
                    312: #define EXT3_IMUL  5
                    313: #define EXT3_DIV   6
                    314: #define EXT3_IDIV  7
                    315: 
                    316: /* Group 5 opcode extensions for 0xff.  To be used with OPC_GRP5.  */
                    317: #define EXT5_INC_Ev    0
                    318: #define EXT5_DEC_Ev    1
                    319: #define EXT5_CALLN_Ev  2
                    320: #define EXT5_JMPN_Ev   4
                    321: 
                    322: /* Condition codes to be added to OPC_JCC_{long,short}.  */
1.1       root      323: #define JCC_JMP (-1)
                    324: #define JCC_JO  0x0
                    325: #define JCC_JNO 0x1
                    326: #define JCC_JB  0x2
                    327: #define JCC_JAE 0x3
                    328: #define JCC_JE  0x4
                    329: #define JCC_JNE 0x5
                    330: #define JCC_JBE 0x6
                    331: #define JCC_JA  0x7
                    332: #define JCC_JS  0x8
                    333: #define JCC_JNS 0x9
                    334: #define JCC_JP  0xa
                    335: #define JCC_JNP 0xb
                    336: #define JCC_JL  0xc
                    337: #define JCC_JGE 0xd
                    338: #define JCC_JLE 0xe
                    339: #define JCC_JG  0xf
                    340: 
                    341: static const uint8_t tcg_cond_to_jcc[10] = {
                    342:     [TCG_COND_EQ] = JCC_JE,
                    343:     [TCG_COND_NE] = JCC_JNE,
                    344:     [TCG_COND_LT] = JCC_JL,
                    345:     [TCG_COND_GE] = JCC_JGE,
                    346:     [TCG_COND_LE] = JCC_JLE,
                    347:     [TCG_COND_GT] = JCC_JG,
                    348:     [TCG_COND_LTU] = JCC_JB,
                    349:     [TCG_COND_GEU] = JCC_JAE,
                    350:     [TCG_COND_LEU] = JCC_JBE,
                    351:     [TCG_COND_GTU] = JCC_JA,
                    352: };
                    353: 
1.1.1.4   root      354: #if TCG_TARGET_REG_BITS == 64
                    355: static void tcg_out_opc(TCGContext *s, int opc, int r, int rm, int x)
1.1       root      356: {
1.1.1.4   root      357:     int rex;
                    358: 
                    359:     if (opc & P_DATA16) {
                    360:         /* We should never be asking for both 16 and 64-bit operation.  */
                    361:         assert((opc & P_REXW) == 0);
                    362:         tcg_out8(s, 0x66);
                    363:     }
                    364:     if (opc & P_ADDR32) {
                    365:         tcg_out8(s, 0x67);
                    366:     }
                    367: 
                    368:     rex = 0;
                    369:     rex |= (opc & P_REXW) >> 8;                /* REX.W */
                    370:     rex |= (r & 8) >> 1;               /* REX.R */
                    371:     rex |= (x & 8) >> 2;               /* REX.X */
                    372:     rex |= (rm & 8) >> 3;              /* REX.B */
                    373: 
                    374:     /* P_REXB_{R,RM} indicates that the given register is the low byte.
                    375:        For %[abcd]l we need no REX prefix, but for %{si,di,bp,sp}l we do,
                    376:        as otherwise the encoding indicates %[abcd]h.  Note that the values
                    377:        that are ORed in merely indicate that the REX byte must be present;
                    378:        those bits get discarded in output.  */
                    379:     rex |= opc & (r >= 4 ? P_REXB_R : 0);
                    380:     rex |= opc & (rm >= 4 ? P_REXB_RM : 0);
                    381: 
                    382:     if (rex) {
                    383:         tcg_out8(s, (uint8_t)(rex | 0x40));
                    384:     }
                    385: 
                    386:     if (opc & P_EXT) {
1.1       root      387:         tcg_out8(s, 0x0f);
1.1.1.4   root      388:     }
1.1       root      389:     tcg_out8(s, opc);
                    390: }
1.1.1.4   root      391: #else
                    392: static void tcg_out_opc(TCGContext *s, int opc)
1.1       root      393: {
1.1.1.4   root      394:     if (opc & P_DATA16) {
                    395:         tcg_out8(s, 0x66);
                    396:     }
                    397:     if (opc & P_EXT) {
                    398:         tcg_out8(s, 0x0f);
                    399:     }
                    400:     tcg_out8(s, opc);
1.1       root      401: }
1.1.1.4   root      402: /* Discard the register arguments to tcg_out_opc early, so as not to penalize
                    403:    the 32-bit compilation paths.  This method works with all versions of gcc,
                    404:    whereas relying on optimization may not be able to exclude them.  */
                    405: #define tcg_out_opc(s, opc, r, rm, x)  (tcg_out_opc)(s, opc)
                    406: #endif
                    407: 
                    408: static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
                    409: {
                    410:     tcg_out_opc(s, opc, r, rm, 0);
                    411:     tcg_out8(s, 0xc0 | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
                    412: }
                    413: 
                    414: /* Output an opcode with a full "rm + (index<<shift) + offset" address mode.
                    415:    We handle either RM and INDEX missing with a negative value.  In 64-bit
                    416:    mode for absolute addresses, ~RM is the size of the immediate operand
                    417:    that will follow the instruction.  */
                    418: 
                    419: static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
                    420:                                      int index, int shift,
                    421:                                      tcg_target_long offset)
                    422: {
                    423:     int mod, len;
                    424: 
                    425:     if (index < 0 && rm < 0) {
                    426:         if (TCG_TARGET_REG_BITS == 64) {
                    427:             /* Try for a rip-relative addressing mode.  This has replaced
                    428:                the 32-bit-mode absolute addressing encoding.  */
                    429:             tcg_target_long pc = (tcg_target_long)s->code_ptr + 5 + ~rm;
                    430:             tcg_target_long disp = offset - pc;
                    431:             if (disp == (int32_t)disp) {
                    432:                 tcg_out_opc(s, opc, r, 0, 0);
                    433:                 tcg_out8(s, (LOWREGMASK(r) << 3) | 5);
                    434:                 tcg_out32(s, disp);
                    435:                 return;
                    436:             }
1.1       root      437: 
1.1.1.4   root      438:             /* Try for an absolute address encoding.  This requires the
                    439:                use of the MODRM+SIB encoding and is therefore larger than
                    440:                rip-relative addressing.  */
                    441:             if (offset == (int32_t)offset) {
                    442:                 tcg_out_opc(s, opc, r, 0, 0);
                    443:                 tcg_out8(s, (LOWREGMASK(r) << 3) | 4);
                    444:                 tcg_out8(s, (4 << 3) | 5);
                    445:                 tcg_out32(s, offset);
                    446:                 return;
                    447:             }
                    448: 
                    449:             /* ??? The memory isn't directly addressable.  */
                    450:             tcg_abort();
1.1       root      451:         } else {
1.1.1.4   root      452:             /* Absolute address.  */
                    453:             tcg_out_opc(s, opc, r, 0, 0);
                    454:             tcg_out8(s, (r << 3) | 5);
                    455:             tcg_out32(s, offset);
                    456:             return;
1.1       root      457:         }
1.1.1.4   root      458:     }
                    459: 
                    460:     /* Find the length of the immediate addend.  Note that the encoding
                    461:        that would be used for (%ebp) indicates absolute addressing.  */
                    462:     if (rm < 0) {
                    463:         mod = 0, len = 4, rm = 5;
                    464:     } else if (offset == 0 && LOWREGMASK(rm) != TCG_REG_EBP) {
                    465:         mod = 0, len = 0;
                    466:     } else if (offset == (int8_t)offset) {
                    467:         mod = 0x40, len = 1;
                    468:     } else {
                    469:         mod = 0x80, len = 4;
                    470:     }
                    471: 
                    472:     /* Use a single byte MODRM format if possible.  Note that the encoding
                    473:        that would be used for %esp is the escape to the two byte form.  */
                    474:     if (index < 0 && LOWREGMASK(rm) != TCG_REG_ESP) {
                    475:         /* Single byte MODRM format.  */
                    476:         tcg_out_opc(s, opc, r, rm, 0);
                    477:         tcg_out8(s, mod | (LOWREGMASK(r) << 3) | LOWREGMASK(rm));
1.1       root      478:     } else {
1.1.1.4   root      479:         /* Two byte MODRM+SIB format.  */
                    480: 
                    481:         /* Note that the encoding that would place %esp into the index
                    482:            field indicates no index register.  In 64-bit mode, the REX.X
                    483:            bit counts, so %r12 can be used as the index.  */
                    484:         if (index < 0) {
                    485:             index = 4;
1.1       root      486:         } else {
1.1.1.4   root      487:             assert(index != TCG_REG_ESP);
1.1       root      488:         }
1.1.1.4   root      489: 
                    490:         tcg_out_opc(s, opc, r, rm, index);
                    491:         tcg_out8(s, mod | (LOWREGMASK(r) << 3) | 4);
                    492:         tcg_out8(s, (shift << 6) | (LOWREGMASK(index) << 3) | LOWREGMASK(rm));
                    493:     }
                    494: 
                    495:     if (len == 1) {
                    496:         tcg_out8(s, offset);
                    497:     } else if (len == 4) {
1.1       root      498:         tcg_out32(s, offset);
                    499:     }
                    500: }
                    501: 
1.1.1.4   root      502: /* A simplification of the above with no index or shift.  */
                    503: static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r,
                    504:                                         int rm, tcg_target_long offset)
                    505: {
                    506:     tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset);
                    507: }
                    508: 
                    509: /* Generate dest op= src.  Uses the same ARITH_* codes as tgen_arithi.  */
                    510: static inline void tgen_arithr(TCGContext *s, int subop, int dest, int src)
1.1       root      511: {
1.1.1.4   root      512:     /* Propagate an opcode prefix, such as P_REXW.  */
                    513:     int ext = subop & ~0x7;
                    514:     subop &= 0x7;
                    515: 
                    516:     tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src);
1.1       root      517: }
                    518: 
1.1.1.6   root      519: static inline void tcg_out_mov(TCGContext *s, TCGType type,
                    520:                                TCGReg ret, TCGReg arg)
1.1.1.4   root      521: {
                    522:     if (arg != ret) {
                    523:         int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
                    524:         tcg_out_modrm(s, opc, ret, arg);
                    525:     }
                    526: }
                    527: 
                    528: static void tcg_out_movi(TCGContext *s, TCGType type,
1.1.1.6   root      529:                          TCGReg ret, tcg_target_long arg)
1.1       root      530: {
                    531:     if (arg == 0) {
1.1.1.4   root      532:         tgen_arithr(s, ARITH_XOR, ret, ret);
                    533:         return;
                    534:     } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
                    535:         tcg_out_opc(s, OPC_MOVL_Iv + LOWREGMASK(ret), 0, ret, 0);
                    536:         tcg_out32(s, arg);
                    537:     } else if (arg == (int32_t)arg) {
                    538:         tcg_out_modrm(s, OPC_MOVL_EvIz + P_REXW, 0, ret);
                    539:         tcg_out32(s, arg);
1.1       root      540:     } else {
1.1.1.4   root      541:         tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
1.1       root      542:         tcg_out32(s, arg);
1.1.1.4   root      543:         tcg_out32(s, arg >> 31 >> 1);
                    544:     }
                    545: }
                    546: 
                    547: static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
                    548: {
                    549:     if (val == (int8_t)val) {
                    550:         tcg_out_opc(s, OPC_PUSH_Ib, 0, 0, 0);
                    551:         tcg_out8(s, val);
                    552:     } else if (val == (int32_t)val) {
                    553:         tcg_out_opc(s, OPC_PUSH_Iv, 0, 0, 0);
                    554:         tcg_out32(s, val);
                    555:     } else {
                    556:         tcg_abort();
1.1       root      557:     }
                    558: }
                    559: 
1.1.1.4   root      560: static inline void tcg_out_push(TCGContext *s, int reg)
                    561: {
                    562:     tcg_out_opc(s, OPC_PUSH_r32 + LOWREGMASK(reg), 0, reg, 0);
                    563: }
                    564: 
                    565: static inline void tcg_out_pop(TCGContext *s, int reg)
                    566: {
                    567:     tcg_out_opc(s, OPC_POP_r32 + LOWREGMASK(reg), 0, reg, 0);
                    568: }
                    569: 
1.1.1.6   root      570: static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
                    571:                               TCGReg arg1, tcg_target_long arg2)
1.1       root      572: {
1.1.1.4   root      573:     int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
                    574:     tcg_out_modrm_offset(s, opc, ret, arg1, arg2);
1.1       root      575: }
                    576: 
1.1.1.6   root      577: static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
                    578:                               TCGReg arg1, tcg_target_long arg2)
1.1       root      579: {
1.1.1.4   root      580:     int opc = OPC_MOVL_EvGv + (type == TCG_TYPE_I64 ? P_REXW : 0);
                    581:     tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
1.1       root      582: }
                    583: 
1.1.1.4   root      584: static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
1.1       root      585: {
1.1.1.4   root      586:     /* Propagate an opcode prefix, such as P_DATA16.  */
                    587:     int ext = subopc & ~0x7;
                    588:     subopc &= 0x7;
                    589: 
                    590:     if (count == 1) {
                    591:         tcg_out_modrm(s, OPC_SHIFT_1 + ext, subopc, reg);
1.1       root      592:     } else {
1.1.1.4   root      593:         tcg_out_modrm(s, OPC_SHIFT_Ib + ext, subopc, reg);
                    594:         tcg_out8(s, count);
                    595:     }
                    596: }
                    597: 
                    598: static inline void tcg_out_bswap32(TCGContext *s, int reg)
                    599: {
                    600:     tcg_out_opc(s, OPC_BSWAP + LOWREGMASK(reg), 0, reg, 0);
                    601: }
                    602: 
                    603: static inline void tcg_out_rolw_8(TCGContext *s, int reg)
                    604: {
                    605:     tcg_out_shifti(s, SHIFT_ROL + P_DATA16, reg, 8);
                    606: }
                    607: 
                    608: static inline void tcg_out_ext8u(TCGContext *s, int dest, int src)
                    609: {
                    610:     /* movzbl */
                    611:     assert(src < 4 || TCG_TARGET_REG_BITS == 64);
                    612:     tcg_out_modrm(s, OPC_MOVZBL + P_REXB_RM, dest, src);
                    613: }
                    614: 
                    615: static void tcg_out_ext8s(TCGContext *s, int dest, int src, int rexw)
                    616: {
                    617:     /* movsbl */
                    618:     assert(src < 4 || TCG_TARGET_REG_BITS == 64);
                    619:     tcg_out_modrm(s, OPC_MOVSBL + P_REXB_RM + rexw, dest, src);
                    620: }
                    621: 
                    622: static inline void tcg_out_ext16u(TCGContext *s, int dest, int src)
                    623: {
                    624:     /* movzwl */
                    625:     tcg_out_modrm(s, OPC_MOVZWL, dest, src);
                    626: }
                    627: 
                    628: static inline void tcg_out_ext16s(TCGContext *s, int dest, int src, int rexw)
                    629: {
                    630:     /* movsw[lq] */
                    631:     tcg_out_modrm(s, OPC_MOVSWL + rexw, dest, src);
                    632: }
                    633: 
                    634: static inline void tcg_out_ext32u(TCGContext *s, int dest, int src)
                    635: {
                    636:     /* 32-bit mov zero extends.  */
                    637:     tcg_out_modrm(s, OPC_MOVL_GvEv, dest, src);
                    638: }
                    639: 
                    640: static inline void tcg_out_ext32s(TCGContext *s, int dest, int src)
                    641: {
                    642:     tcg_out_modrm(s, OPC_MOVSLQ, dest, src);
                    643: }
                    644: 
                    645: static inline void tcg_out_bswap64(TCGContext *s, int reg)
                    646: {
                    647:     tcg_out_opc(s, OPC_BSWAP + P_REXW + LOWREGMASK(reg), 0, reg, 0);
                    648: }
                    649: 
                    650: static void tgen_arithi(TCGContext *s, int c, int r0,
                    651:                         tcg_target_long val, int cf)
                    652: {
                    653:     int rexw = 0;
                    654: 
                    655:     if (TCG_TARGET_REG_BITS == 64) {
                    656:         rexw = c & -8;
                    657:         c &= 7;
                    658:     }
                    659: 
                    660:     /* ??? While INC is 2 bytes shorter than ADDL $1, they also induce
                    661:        partial flags update stalls on Pentium4 and are not recommended
                    662:        by current Intel optimization manuals.  */
                    663:     if (!cf && (c == ARITH_ADD || c == ARITH_SUB) && (val == 1 || val == -1)) {
                    664:         int is_inc = (c == ARITH_ADD) ^ (val < 0);
                    665:         if (TCG_TARGET_REG_BITS == 64) {
                    666:             /* The single-byte increment encodings are re-tasked as the
                    667:                REX prefixes.  Use the MODRM encoding.  */
                    668:             tcg_out_modrm(s, OPC_GRP5 + rexw,
                    669:                           (is_inc ? EXT5_INC_Ev : EXT5_DEC_Ev), r0);
                    670:         } else {
                    671:             tcg_out8(s, (is_inc ? OPC_INC_r32 : OPC_DEC_r32) + r0);
                    672:         }
                    673:         return;
                    674:     }
                    675: 
                    676:     if (c == ARITH_AND) {
                    677:         if (TCG_TARGET_REG_BITS == 64) {
                    678:             if (val == 0xffffffffu) {
                    679:                 tcg_out_ext32u(s, r0, r0);
                    680:                 return;
                    681:             }
                    682:             if (val == (uint32_t)val) {
                    683:                 /* AND with no high bits set can use a 32-bit operation.  */
                    684:                 rexw = 0;
                    685:             }
                    686:         }
                    687:         if (val == 0xffu && (r0 < 4 || TCG_TARGET_REG_BITS == 64)) {
                    688:             tcg_out_ext8u(s, r0, r0);
                    689:             return;
                    690:         }
                    691:         if (val == 0xffffu) {
                    692:             tcg_out_ext16u(s, r0, r0);
                    693:             return;
                    694:         }
                    695:     }
                    696: 
                    697:     if (val == (int8_t)val) {
                    698:         tcg_out_modrm(s, OPC_ARITH_EvIb + rexw, c, r0);
                    699:         tcg_out8(s, val);
                    700:         return;
                    701:     }
                    702:     if (rexw == 0 || val == (int32_t)val) {
                    703:         tcg_out_modrm(s, OPC_ARITH_EvIz + rexw, c, r0);
1.1       root      704:         tcg_out32(s, val);
1.1.1.4   root      705:         return;
1.1       root      706:     }
1.1.1.4   root      707: 
                    708:     tcg_abort();
1.1       root      709: }
                    710: 
                    711: static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
                    712: {
1.1.1.4   root      713:     if (val != 0) {
                    714:         tgen_arithi(s, ARITH_ADD + P_REXW, reg, val, 0);
                    715:     }
1.1       root      716: }
                    717: 
1.1.1.4   root      718: /* Use SMALL != 0 to force a short forward branch.  */
                    719: static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
1.1       root      720: {
                    721:     int32_t val, val1;
                    722:     TCGLabel *l = &s->labels[label_index];
1.1.1.4   root      723: 
1.1       root      724:     if (l->has_value) {
                    725:         val = l->u.value - (tcg_target_long)s->code_ptr;
                    726:         val1 = val - 2;
                    727:         if ((int8_t)val1 == val1) {
1.1.1.4   root      728:             if (opc == -1) {
                    729:                 tcg_out8(s, OPC_JMP_short);
                    730:             } else {
                    731:                 tcg_out8(s, OPC_JCC_short + opc);
                    732:             }
1.1       root      733:             tcg_out8(s, val1);
                    734:         } else {
1.1.1.4   root      735:             if (small) {
                    736:                 tcg_abort();
                    737:             }
1.1       root      738:             if (opc == -1) {
1.1.1.4   root      739:                 tcg_out8(s, OPC_JMP_long);
1.1       root      740:                 tcg_out32(s, val - 5);
                    741:             } else {
1.1.1.4   root      742:                 tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
1.1       root      743:                 tcg_out32(s, val - 6);
                    744:             }
                    745:         }
1.1.1.4   root      746:     } else if (small) {
                    747:         if (opc == -1) {
                    748:             tcg_out8(s, OPC_JMP_short);
                    749:         } else {
                    750:             tcg_out8(s, OPC_JCC_short + opc);
                    751:         }
                    752:         tcg_out_reloc(s, s->code_ptr, R_386_PC8, label_index, -1);
                    753:         s->code_ptr += 1;
1.1       root      754:     } else {
                    755:         if (opc == -1) {
1.1.1.4   root      756:             tcg_out8(s, OPC_JMP_long);
1.1       root      757:         } else {
1.1.1.4   root      758:             tcg_out_opc(s, OPC_JCC_long + opc, 0, 0, 0);
1.1       root      759:         }
                    760:         tcg_out_reloc(s, s->code_ptr, R_386_PC32, label_index, -4);
                    761:         s->code_ptr += 4;
                    762:     }
                    763: }
                    764: 
1.1.1.4   root      765: static void tcg_out_cmp(TCGContext *s, TCGArg arg1, TCGArg arg2,
                    766:                         int const_arg2, int rexw)
1.1       root      767: {
                    768:     if (const_arg2) {
                    769:         if (arg2 == 0) {
                    770:             /* test r, r */
1.1.1.4   root      771:             tcg_out_modrm(s, OPC_TESTL + rexw, arg1, arg1);
1.1       root      772:         } else {
1.1.1.4   root      773:             tgen_arithi(s, ARITH_CMP + rexw, arg1, arg2, 0);
1.1       root      774:         }
                    775:     } else {
1.1.1.4   root      776:         tgen_arithr(s, ARITH_CMP + rexw, arg1, arg2);
1.1       root      777:     }
                    778: }
                    779: 
1.1.1.4   root      780: static void tcg_out_brcond32(TCGContext *s, TCGCond cond,
                    781:                              TCGArg arg1, TCGArg arg2, int const_arg2,
                    782:                              int label_index, int small)
                    783: {
                    784:     tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
                    785:     tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
                    786: }
                    787: 
                    788: #if TCG_TARGET_REG_BITS == 64
                    789: static void tcg_out_brcond64(TCGContext *s, TCGCond cond,
                    790:                              TCGArg arg1, TCGArg arg2, int const_arg2,
                    791:                              int label_index, int small)
                    792: {
                    793:     tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
                    794:     tcg_out_jxx(s, tcg_cond_to_jcc[cond], label_index, small);
                    795: }
                    796: #else
1.1       root      797: /* XXX: we implement it at the target level to avoid having to
                    798:    handle cross basic blocks temporaries */
1.1.1.4   root      799: static void tcg_out_brcond2(TCGContext *s, const TCGArg *args,
                    800:                             const int *const_args, int small)
1.1       root      801: {
                    802:     int label_next;
                    803:     label_next = gen_new_label();
                    804:     switch(args[4]) {
                    805:     case TCG_COND_EQ:
1.1.1.4   root      806:         tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
                    807:                          label_next, 1);
                    808:         tcg_out_brcond32(s, TCG_COND_EQ, args[1], args[3], const_args[3],
                    809:                          args[5], small);
1.1       root      810:         break;
                    811:     case TCG_COND_NE:
1.1.1.4   root      812:         tcg_out_brcond32(s, TCG_COND_NE, args[0], args[2], const_args[2],
                    813:                          args[5], small);
                    814:         tcg_out_brcond32(s, TCG_COND_NE, args[1], args[3], const_args[3],
                    815:                          args[5], small);
1.1       root      816:         break;
                    817:     case TCG_COND_LT:
1.1.1.4   root      818:         tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
                    819:                          args[5], small);
                    820:         tcg_out_jxx(s, JCC_JNE, label_next, 1);
                    821:         tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
                    822:                          args[5], small);
1.1       root      823:         break;
                    824:     case TCG_COND_LE:
1.1.1.4   root      825:         tcg_out_brcond32(s, TCG_COND_LT, args[1], args[3], const_args[3],
                    826:                          args[5], small);
                    827:         tcg_out_jxx(s, JCC_JNE, label_next, 1);
                    828:         tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
                    829:                          args[5], small);
1.1       root      830:         break;
                    831:     case TCG_COND_GT:
1.1.1.4   root      832:         tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
                    833:                          args[5], small);
                    834:         tcg_out_jxx(s, JCC_JNE, label_next, 1);
                    835:         tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
                    836:                          args[5], small);
1.1       root      837:         break;
                    838:     case TCG_COND_GE:
1.1.1.4   root      839:         tcg_out_brcond32(s, TCG_COND_GT, args[1], args[3], const_args[3],
                    840:                          args[5], small);
                    841:         tcg_out_jxx(s, JCC_JNE, label_next, 1);
                    842:         tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
                    843:                          args[5], small);
1.1       root      844:         break;
                    845:     case TCG_COND_LTU:
1.1.1.4   root      846:         tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
                    847:                          args[5], small);
                    848:         tcg_out_jxx(s, JCC_JNE, label_next, 1);
                    849:         tcg_out_brcond32(s, TCG_COND_LTU, args[0], args[2], const_args[2],
                    850:                          args[5], small);
1.1       root      851:         break;
                    852:     case TCG_COND_LEU:
1.1.1.4   root      853:         tcg_out_brcond32(s, TCG_COND_LTU, args[1], args[3], const_args[3],
                    854:                          args[5], small);
                    855:         tcg_out_jxx(s, JCC_JNE, label_next, 1);
                    856:         tcg_out_brcond32(s, TCG_COND_LEU, args[0], args[2], const_args[2],
                    857:                          args[5], small);
1.1       root      858:         break;
                    859:     case TCG_COND_GTU:
1.1.1.4   root      860:         tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
                    861:                          args[5], small);
                    862:         tcg_out_jxx(s, JCC_JNE, label_next, 1);
                    863:         tcg_out_brcond32(s, TCG_COND_GTU, args[0], args[2], const_args[2],
                    864:                          args[5], small);
1.1       root      865:         break;
                    866:     case TCG_COND_GEU:
1.1.1.4   root      867:         tcg_out_brcond32(s, TCG_COND_GTU, args[1], args[3], const_args[3],
                    868:                          args[5], small);
                    869:         tcg_out_jxx(s, JCC_JNE, label_next, 1);
                    870:         tcg_out_brcond32(s, TCG_COND_GEU, args[0], args[2], const_args[2],
                    871:                          args[5], small);
1.1       root      872:         break;
                    873:     default:
                    874:         tcg_abort();
                    875:     }
1.1.1.7 ! root      876:     tcg_out_label(s, label_next, s->code_ptr);
1.1       root      877: }
1.1.1.4   root      878: #endif
                    879: 
                    880: static void tcg_out_setcond32(TCGContext *s, TCGCond cond, TCGArg dest,
                    881:                               TCGArg arg1, TCGArg arg2, int const_arg2)
                    882: {
                    883:     tcg_out_cmp(s, arg1, arg2, const_arg2, 0);
                    884:     tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
                    885:     tcg_out_ext8u(s, dest, dest);
                    886: }
                    887: 
                    888: #if TCG_TARGET_REG_BITS == 64
                    889: static void tcg_out_setcond64(TCGContext *s, TCGCond cond, TCGArg dest,
                    890:                               TCGArg arg1, TCGArg arg2, int const_arg2)
                    891: {
                    892:     tcg_out_cmp(s, arg1, arg2, const_arg2, P_REXW);
                    893:     tcg_out_modrm(s, OPC_SETCC | tcg_cond_to_jcc[cond], 0, dest);
                    894:     tcg_out_ext8u(s, dest, dest);
                    895: }
                    896: #else
                    897: static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
                    898:                              const int *const_args)
                    899: {
                    900:     TCGArg new_args[6];
                    901:     int label_true, label_over;
                    902: 
                    903:     memcpy(new_args, args+1, 5*sizeof(TCGArg));
                    904: 
                    905:     if (args[0] == args[1] || args[0] == args[2]
                    906:         || (!const_args[3] && args[0] == args[3])
                    907:         || (!const_args[4] && args[0] == args[4])) {
                    908:         /* When the destination overlaps with one of the argument
                    909:            registers, don't do anything tricky.  */
                    910:         label_true = gen_new_label();
                    911:         label_over = gen_new_label();
                    912: 
                    913:         new_args[5] = label_true;
                    914:         tcg_out_brcond2(s, new_args, const_args+1, 1);
                    915: 
                    916:         tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
                    917:         tcg_out_jxx(s, JCC_JMP, label_over, 1);
1.1.1.7 ! root      918:         tcg_out_label(s, label_true, s->code_ptr);
1.1.1.4   root      919: 
                    920:         tcg_out_movi(s, TCG_TYPE_I32, args[0], 1);
1.1.1.7 ! root      921:         tcg_out_label(s, label_over, s->code_ptr);
1.1.1.4   root      922:     } else {
                    923:         /* When the destination does not overlap one of the arguments,
                    924:            clear the destination first, jump if cond false, and emit an
                    925:            increment in the true case.  This results in smaller code.  */
                    926: 
                    927:         tcg_out_movi(s, TCG_TYPE_I32, args[0], 0);
                    928: 
                    929:         label_over = gen_new_label();
                    930:         new_args[4] = tcg_invert_cond(new_args[4]);
                    931:         new_args[5] = label_over;
                    932:         tcg_out_brcond2(s, new_args, const_args+1, 1);
                    933: 
                    934:         tgen_arithi(s, ARITH_ADD, args[0], 1, 0);
1.1.1.7 ! root      935:         tcg_out_label(s, label_over, s->code_ptr);
1.1.1.4   root      936:     }
                    937: }
                    938: #endif
                    939: 
                    940: static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
                    941: {
                    942:     tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5;
                    943: 
                    944:     if (disp == (int32_t)disp) {
                    945:         tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0);
                    946:         tcg_out32(s, disp);
                    947:     } else {
                    948:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R10, dest);
                    949:         tcg_out_modrm(s, OPC_GRP5,
                    950:                       call ? EXT5_CALLN_Ev : EXT5_JMPN_Ev, TCG_REG_R10);
                    951:     }
                    952: }
                    953: 
                    954: static inline void tcg_out_calli(TCGContext *s, tcg_target_long dest)
                    955: {
                    956:     tcg_out_branch(s, 1, dest);
                    957: }
                    958: 
                    959: static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
                    960: {
                    961:     tcg_out_branch(s, 0, dest);
                    962: }
1.1       root      963: 
                    964: #if defined(CONFIG_SOFTMMU)
                    965: 
                    966: #include "../../softmmu_defs.h"
                    967: 
1.1.1.7 ! root      968: #ifdef CONFIG_TCG_PASS_AREG0
        !           969: /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
        !           970:    int mmu_idx) */
        !           971: static const void *qemu_ld_helpers[4] = {
        !           972:     helper_ldb_mmu,
        !           973:     helper_ldw_mmu,
        !           974:     helper_ldl_mmu,
        !           975:     helper_ldq_mmu,
        !           976: };
        !           977: 
        !           978: /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
        !           979:    uintxx_t val, int mmu_idx) */
        !           980: static const void *qemu_st_helpers[4] = {
        !           981:     helper_stb_mmu,
        !           982:     helper_stw_mmu,
        !           983:     helper_stl_mmu,
        !           984:     helper_stq_mmu,
        !           985: };
        !           986: #else
        !           987: /* legacy helper signature: __ld_mmu(target_ulong addr, int
        !           988:    mmu_idx) */
1.1       root      989: static void *qemu_ld_helpers[4] = {
                    990:     __ldb_mmu,
                    991:     __ldw_mmu,
                    992:     __ldl_mmu,
                    993:     __ldq_mmu,
                    994: };
                    995: 
1.1.1.7 ! root      996: /* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
        !           997:    int mmu_idx) */
1.1       root      998: static void *qemu_st_helpers[4] = {
                    999:     __stb_mmu,
                   1000:     __stw_mmu,
                   1001:     __stl_mmu,
                   1002:     __stq_mmu,
                   1003: };
1.1.1.7 ! root     1004: #endif
1.1.1.4   root     1005: 
                   1006: /* Perform the TLB load and compare.
                   1007: 
                   1008:    Inputs:
                   1009:    ADDRLO_IDX contains the index into ARGS of the low part of the
                   1010:    address; the high part of the address is at ADDR_LOW_IDX+1.
                   1011: 
                   1012:    MEM_INDEX and S_BITS are the memory context and log2 size of the load.
                   1013: 
                   1014:    WHICH is the offset into the CPUTLBEntry structure of the slot to read.
                   1015:    This should be offsetof addr_read or addr_write.
                   1016: 
                   1017:    Outputs:
                   1018:    LABEL_PTRS is filled with 1 (32-bit addresses) or 2 (64-bit addresses)
                   1019:    positions of the displacements of forward jumps to the TLB miss case.
                   1020: 
                   1021:    First argument register is loaded with the low part of the address.
                   1022:    In the TLB hit case, it has been adjusted as indicated by the TLB
                   1023:    and so is a host address.  In the TLB miss case, it continues to
                   1024:    hold a guest address.
                   1025: 
                   1026:    Second argument register is clobbered.  */
                   1027: 
                   1028: static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx,
                   1029:                                     int mem_index, int s_bits,
                   1030:                                     const TCGArg *args,
                   1031:                                     uint8_t **label_ptr, int which)
                   1032: {
                   1033:     const int addrlo = args[addrlo_idx];
                   1034:     const int r0 = tcg_target_call_iarg_regs[0];
                   1035:     const int r1 = tcg_target_call_iarg_regs[1];
                   1036:     TCGType type = TCG_TYPE_I32;
                   1037:     int rexw = 0;
                   1038: 
                   1039:     if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 64) {
                   1040:         type = TCG_TYPE_I64;
                   1041:         rexw = P_REXW;
                   1042:     }
                   1043: 
                   1044:     tcg_out_mov(s, type, r1, addrlo);
                   1045:     tcg_out_mov(s, type, r0, addrlo);
                   1046: 
                   1047:     tcg_out_shifti(s, SHIFT_SHR + rexw, r1,
                   1048:                    TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
                   1049: 
                   1050:     tgen_arithi(s, ARITH_AND + rexw, r0,
                   1051:                 TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
                   1052:     tgen_arithi(s, ARITH_AND + rexw, r1,
                   1053:                 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
                   1054: 
                   1055:     tcg_out_modrm_sib_offset(s, OPC_LEA + P_REXW, r1, TCG_AREG0, r1, 0,
1.1.1.7 ! root     1056:                              offsetof(CPUArchState, tlb_table[mem_index][0])
1.1.1.4   root     1057:                              + which);
                   1058: 
                   1059:     /* cmp 0(r1), r0 */
                   1060:     tcg_out_modrm_offset(s, OPC_CMP_GvEv + rexw, r0, r1, 0);
                   1061: 
                   1062:     tcg_out_mov(s, type, r0, addrlo);
                   1063: 
                   1064:     /* jne label1 */
                   1065:     tcg_out8(s, OPC_JCC_short + JCC_JNE);
                   1066:     label_ptr[0] = s->code_ptr;
                   1067:     s->code_ptr++;
                   1068: 
                   1069:     if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
                   1070:         /* cmp 4(r1), addrhi */
                   1071:         tcg_out_modrm_offset(s, OPC_CMP_GvEv, args[addrlo_idx+1], r1, 4);
                   1072: 
                   1073:         /* jne label1 */
                   1074:         tcg_out8(s, OPC_JCC_short + JCC_JNE);
                   1075:         label_ptr[1] = s->code_ptr;
                   1076:         s->code_ptr++;
                   1077:     }
                   1078: 
                   1079:     /* TLB Hit.  */
                   1080: 
                   1081:     /* add addend(r1), r0 */
                   1082:     tcg_out_modrm_offset(s, OPC_ADD_GvEv + P_REXW, r0, r1,
                   1083:                          offsetof(CPUTLBEntry, addend) - which);
                   1084: }
1.1       root     1085: #endif
                   1086: 
1.1.1.4   root     1087: static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
                   1088:                                    int base, tcg_target_long ofs, int sizeop)
                   1089: {
                   1090: #ifdef TARGET_WORDS_BIGENDIAN
                   1091:     const int bswap = 1;
                   1092: #else
                   1093:     const int bswap = 0;
1.1.1.3   root     1094: #endif
1.1.1.4   root     1095:     switch (sizeop) {
                   1096:     case 0:
                   1097:         tcg_out_modrm_offset(s, OPC_MOVZBL, datalo, base, ofs);
                   1098:         break;
                   1099:     case 0 | 4:
                   1100:         tcg_out_modrm_offset(s, OPC_MOVSBL + P_REXW, datalo, base, ofs);
                   1101:         break;
                   1102:     case 1:
                   1103:         tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
                   1104:         if (bswap) {
                   1105:             tcg_out_rolw_8(s, datalo);
                   1106:         }
                   1107:         break;
                   1108:     case 1 | 4:
                   1109:         if (bswap) {
                   1110:             tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
                   1111:             tcg_out_rolw_8(s, datalo);
                   1112:             tcg_out_modrm(s, OPC_MOVSWL + P_REXW, datalo, datalo);
                   1113:         } else {
                   1114:             tcg_out_modrm_offset(s, OPC_MOVSWL + P_REXW, datalo, base, ofs);
                   1115:         }
                   1116:         break;
                   1117:     case 2:
                   1118:         tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
                   1119:         if (bswap) {
                   1120:             tcg_out_bswap32(s, datalo);
                   1121:         }
                   1122:         break;
                   1123: #if TCG_TARGET_REG_BITS == 64
                   1124:     case 2 | 4:
                   1125:         if (bswap) {
                   1126:             tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
                   1127:             tcg_out_bswap32(s, datalo);
                   1128:             tcg_out_ext32s(s, datalo, datalo);
                   1129:         } else {
                   1130:             tcg_out_modrm_offset(s, OPC_MOVSLQ, datalo, base, ofs);
                   1131:         }
                   1132:         break;
                   1133: #endif
                   1134:     case 3:
                   1135:         if (TCG_TARGET_REG_BITS == 64) {
                   1136:             tcg_out_ld(s, TCG_TYPE_I64, datalo, base, ofs);
                   1137:             if (bswap) {
                   1138:                 tcg_out_bswap64(s, datalo);
                   1139:             }
                   1140:         } else {
                   1141:             if (bswap) {
                   1142:                 int t = datalo;
                   1143:                 datalo = datahi;
                   1144:                 datahi = t;
                   1145:             }
                   1146:             if (base != datalo) {
                   1147:                 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
                   1148:                 tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
                   1149:             } else {
                   1150:                 tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
                   1151:                 tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
                   1152:             }
                   1153:             if (bswap) {
                   1154:                 tcg_out_bswap32(s, datalo);
                   1155:                 tcg_out_bswap32(s, datahi);
                   1156:             }
                   1157:         }
                   1158:         break;
                   1159:     default:
                   1160:         tcg_abort();
                   1161:     }
                   1162: }
1.1.1.3   root     1163: 
1.1       root     1164: /* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
                   1165:    EAX. It will be useful once fixed registers globals are less
                   1166:    common. */
                   1167: static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
                   1168:                             int opc)
                   1169: {
1.1.1.4   root     1170:     int data_reg, data_reg2 = 0;
                   1171:     int addrlo_idx;
1.1       root     1172: #if defined(CONFIG_SOFTMMU)
1.1.1.7 ! root     1173:     int mem_index, s_bits;
        !          1174: #if TCG_TARGET_REG_BITS == 64
        !          1175:     int arg_idx;
        !          1176: #else
        !          1177:     int stack_adjust;
        !          1178: #endif
1.1.1.4   root     1179:     uint8_t *label_ptr[3];
1.1       root     1180: #endif
                   1181: 
1.1.1.4   root     1182:     data_reg = args[0];
                   1183:     addrlo_idx = 1;
                   1184:     if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
                   1185:         data_reg2 = args[1];
                   1186:         addrlo_idx = 2;
                   1187:     }
1.1       root     1188: 
                   1189: #if defined(CONFIG_SOFTMMU)
1.1.1.4   root     1190:     mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
                   1191:     s_bits = opc & 3;
1.1       root     1192: 
1.1.1.4   root     1193:     tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
                   1194:                      label_ptr, offsetof(CPUTLBEntry, addr_read));
1.1       root     1195: 
1.1.1.4   root     1196:     /* TLB Hit.  */
                   1197:     tcg_out_qemu_ld_direct(s, data_reg, data_reg2,
                   1198:                            tcg_target_call_iarg_regs[0], 0, opc);
                   1199: 
                   1200:     /* jmp label2 */
                   1201:     tcg_out8(s, OPC_JMP_short);
                   1202:     label_ptr[2] = s->code_ptr;
1.1       root     1203:     s->code_ptr++;
1.1.1.4   root     1204: 
                   1205:     /* TLB Miss.  */
                   1206: 
                   1207:     /* label1: */
                   1208:     *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
                   1209:     if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
                   1210:         *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
                   1211:     }
1.1       root     1212: 
                   1213:     /* XXX: move that code at the end of the TB */
1.1.1.7 ! root     1214: #if TCG_TARGET_REG_BITS == 32
        !          1215:     tcg_out_pushi(s, mem_index);
        !          1216:     stack_adjust = 4;
        !          1217:     if (TARGET_LONG_BITS == 64) {
        !          1218:         tcg_out_push(s, args[addrlo_idx + 1]);
        !          1219:         stack_adjust += 4;
        !          1220:     }
        !          1221:     tcg_out_push(s, args[addrlo_idx]);
        !          1222:     stack_adjust += 4;
        !          1223: #ifdef CONFIG_TCG_PASS_AREG0
        !          1224:     tcg_out_push(s, TCG_AREG0);
        !          1225:     stack_adjust += 4;
        !          1226: #endif
        !          1227: #else
1.1.1.4   root     1228:     /* The first argument is already loaded with addrlo.  */
                   1229:     arg_idx = 1;
                   1230:     tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx],
                   1231:                  mem_index);
1.1.1.7 ! root     1232: #ifdef CONFIG_TCG_PASS_AREG0
        !          1233:     /* XXX/FIXME: suboptimal */
        !          1234:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
        !          1235:                 tcg_target_call_iarg_regs[2]);
        !          1236:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
        !          1237:                 tcg_target_call_iarg_regs[1]);
        !          1238:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
        !          1239:                 tcg_target_call_iarg_regs[0]);
        !          1240:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
        !          1241:                 TCG_AREG0);
        !          1242: #endif
        !          1243: #endif
        !          1244: 
1.1.1.4   root     1245:     tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
1.1       root     1246: 
1.1.1.7 ! root     1247: #if TCG_TARGET_REG_BITS == 32
        !          1248:     if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
        !          1249:         /* Pop and discard.  This is 2 bytes smaller than the add.  */
        !          1250:         tcg_out_pop(s, TCG_REG_ECX);
        !          1251:     } else if (stack_adjust != 0) {
        !          1252:         tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
        !          1253:     }
        !          1254: #endif
        !          1255: 
1.1       root     1256:     switch(opc) {
                   1257:     case 0 | 4:
1.1.1.4   root     1258:         tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
1.1       root     1259:         break;
                   1260:     case 1 | 4:
1.1.1.4   root     1261:         tcg_out_ext16s(s, data_reg, TCG_REG_EAX, P_REXW);
1.1       root     1262:         break;
                   1263:     case 0:
1.1.1.4   root     1264:         tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
1.1       root     1265:         break;
                   1266:     case 1:
1.1.1.4   root     1267:         tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
1.1       root     1268:         break;
                   1269:     case 2:
1.1.1.4   root     1270:         tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
                   1271:         break;
                   1272: #if TCG_TARGET_REG_BITS == 64
                   1273:     case 2 | 4:
                   1274:         tcg_out_ext32s(s, data_reg, TCG_REG_EAX);
1.1       root     1275:         break;
1.1.1.4   root     1276: #endif
1.1       root     1277:     case 3:
1.1.1.4   root     1278:         if (TCG_TARGET_REG_BITS == 64) {
                   1279:             tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);
                   1280:         } else if (data_reg == TCG_REG_EDX) {
                   1281:             /* xchg %edx, %eax */
                   1282:             tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
                   1283:             tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EAX);
1.1       root     1284:         } else {
1.1.1.4   root     1285:             tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
                   1286:             tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EDX);
1.1       root     1287:         }
                   1288:         break;
1.1.1.4   root     1289:     default:
                   1290:         tcg_abort();
1.1       root     1291:     }
                   1292: 
1.1.1.4   root     1293:     /* label2: */
                   1294:     *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
1.1       root     1295: #else
1.1.1.4   root     1296:     {
                   1297:         int32_t offset = GUEST_BASE;
                   1298:         int base = args[addrlo_idx];
                   1299: 
                   1300:         if (TCG_TARGET_REG_BITS == 64) {
                   1301:             /* ??? We assume all operations have left us with register
                   1302:                contents that are zero extended.  So far this appears to
                   1303:                be true.  If we want to enforce this, we can either do
                   1304:                an explicit zero-extension here, or (if GUEST_BASE == 0)
                   1305:                use the ADDR32 prefix.  For now, do nothing.  */
                   1306: 
                   1307:             if (offset != GUEST_BASE) {
1.1.1.7 ! root     1308:                 tcg_out_movi(s, TCG_TYPE_I64,
        !          1309:                              tcg_target_call_iarg_regs[0], GUEST_BASE);
        !          1310:                 tgen_arithr(s, ARITH_ADD + P_REXW,
        !          1311:                             tcg_target_call_iarg_regs[0], base);
        !          1312:                 base = tcg_target_call_iarg_regs[0];
        !          1313:                 offset = 0;
1.1.1.4   root     1314:             }
                   1315:         }
                   1316: 
                   1317:         tcg_out_qemu_ld_direct(s, data_reg, data_reg2, base, offset, opc);
                   1318:     }
1.1       root     1319: #endif
1.1.1.4   root     1320: }
1.1       root     1321: 
1.1.1.4   root     1322: static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
                   1323:                                    int base, tcg_target_long ofs, int sizeop)
                   1324: {
1.1       root     1325: #ifdef TARGET_WORDS_BIGENDIAN
1.1.1.4   root     1326:     const int bswap = 1;
1.1       root     1327: #else
1.1.1.4   root     1328:     const int bswap = 0;
1.1       root     1329: #endif
1.1.1.4   root     1330:     /* ??? Ideally we wouldn't need a scratch register.  For user-only,
                   1331:        we could perform the bswap twice to restore the original value
                   1332:        instead of moving to the scratch.  But as it is, the L constraint
                   1333:        means that the second argument reg is definitely free here.  */
                   1334:     int scratch = tcg_target_call_iarg_regs[1];
                   1335: 
                   1336:     switch (sizeop) {
1.1       root     1337:     case 0:
1.1.1.4   root     1338:         tcg_out_modrm_offset(s, OPC_MOVB_EvGv + P_REXB_R, datalo, base, ofs);
1.1       root     1339:         break;
                   1340:     case 1:
                   1341:         if (bswap) {
1.1.1.4   root     1342:             tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
                   1343:             tcg_out_rolw_8(s, scratch);
                   1344:             datalo = scratch;
1.1       root     1345:         }
1.1.1.4   root     1346:         tcg_out_modrm_offset(s, OPC_MOVL_EvGv + P_DATA16, datalo, base, ofs);
1.1       root     1347:         break;
                   1348:     case 2:
                   1349:         if (bswap) {
1.1.1.4   root     1350:             tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
                   1351:             tcg_out_bswap32(s, scratch);
                   1352:             datalo = scratch;
1.1       root     1353:         }
1.1.1.4   root     1354:         tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
1.1       root     1355:         break;
                   1356:     case 3:
1.1.1.4   root     1357:         if (TCG_TARGET_REG_BITS == 64) {
                   1358:             if (bswap) {
                   1359:                 tcg_out_mov(s, TCG_TYPE_I64, scratch, datalo);
                   1360:                 tcg_out_bswap64(s, scratch);
                   1361:                 datalo = scratch;
                   1362:             }
                   1363:             tcg_out_st(s, TCG_TYPE_I64, datalo, base, ofs);
                   1364:         } else if (bswap) {
                   1365:             tcg_out_mov(s, TCG_TYPE_I32, scratch, datahi);
                   1366:             tcg_out_bswap32(s, scratch);
                   1367:             tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs);
                   1368:             tcg_out_mov(s, TCG_TYPE_I32, scratch, datalo);
                   1369:             tcg_out_bswap32(s, scratch);
                   1370:             tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs + 4);
                   1371:         } else {
                   1372:             tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
                   1373:             tcg_out_st(s, TCG_TYPE_I32, datahi, base, ofs + 4);
1.1       root     1374:         }
                   1375:         break;
                   1376:     default:
                   1377:         tcg_abort();
                   1378:     }
                   1379: }
                   1380: 
                   1381: static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
                   1382:                             int opc)
                   1383: {
1.1.1.4   root     1384:     int data_reg, data_reg2 = 0;
                   1385:     int addrlo_idx;
1.1       root     1386: #if defined(CONFIG_SOFTMMU)
1.1.1.4   root     1387:     int mem_index, s_bits;
                   1388:     int stack_adjust;
                   1389:     uint8_t *label_ptr[3];
1.1       root     1390: #endif
                   1391: 
1.1.1.4   root     1392:     data_reg = args[0];
                   1393:     addrlo_idx = 1;
                   1394:     if (TCG_TARGET_REG_BITS == 32 && opc == 3) {
                   1395:         data_reg2 = args[1];
                   1396:         addrlo_idx = 2;
                   1397:     }
1.1       root     1398: 
1.1.1.4   root     1399: #if defined(CONFIG_SOFTMMU)
                   1400:     mem_index = args[addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)];
1.1       root     1401:     s_bits = opc;
                   1402: 
1.1.1.4   root     1403:     tcg_out_tlb_load(s, addrlo_idx, mem_index, s_bits, args,
                   1404:                      label_ptr, offsetof(CPUTLBEntry, addr_write));
1.1       root     1405: 
1.1.1.4   root     1406:     /* TLB Hit.  */
                   1407:     tcg_out_qemu_st_direct(s, data_reg, data_reg2,
                   1408:                            tcg_target_call_iarg_regs[0], 0, opc);
1.1       root     1409: 
1.1.1.4   root     1410:     /* jmp label2 */
                   1411:     tcg_out8(s, OPC_JMP_short);
                   1412:     label_ptr[2] = s->code_ptr;
1.1       root     1413:     s->code_ptr++;
1.1.1.4   root     1414: 
                   1415:     /* TLB Miss.  */
                   1416: 
                   1417:     /* label1: */
                   1418:     *label_ptr[0] = s->code_ptr - label_ptr[0] - 1;
                   1419:     if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
                   1420:         *label_ptr[1] = s->code_ptr - label_ptr[1] - 1;
                   1421:     }
1.1       root     1422: 
                   1423:     /* XXX: move that code at the end of the TB */
1.1.1.7 ! root     1424: #if TCG_TARGET_REG_BITS == 32
        !          1425:     tcg_out_pushi(s, mem_index);
        !          1426:     stack_adjust = 4;
        !          1427:     if (opc == 3) {
        !          1428:         tcg_out_push(s, data_reg2);
        !          1429:         stack_adjust += 4;
        !          1430:     }
        !          1431:     tcg_out_push(s, data_reg);
        !          1432:     stack_adjust += 4;
        !          1433:     if (TARGET_LONG_BITS == 64) {
        !          1434:         tcg_out_push(s, args[addrlo_idx + 1]);
        !          1435:         stack_adjust += 4;
        !          1436:     }
        !          1437:     tcg_out_push(s, args[addrlo_idx]);
        !          1438:     stack_adjust += 4;
        !          1439: #ifdef CONFIG_TCG_PASS_AREG0
        !          1440:     tcg_out_push(s, TCG_AREG0);
        !          1441:     stack_adjust += 4;
        !          1442: #endif
        !          1443: #else
        !          1444:     tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
        !          1445:                 tcg_target_call_iarg_regs[1], data_reg);
        !          1446:     tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], mem_index);
        !          1447:     stack_adjust = 0;
        !          1448: #ifdef CONFIG_TCG_PASS_AREG0
        !          1449:     /* XXX/FIXME: suboptimal */
        !          1450:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
        !          1451:                 tcg_target_call_iarg_regs[2]);
        !          1452:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
        !          1453:                 tcg_target_call_iarg_regs[1]);
        !          1454:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
        !          1455:                 tcg_target_call_iarg_regs[0]);
        !          1456:     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
        !          1457:                 TCG_AREG0);
        !          1458: #endif
        !          1459: #endif
1.1       root     1460: 
1.1.1.4   root     1461:     tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
1.1       root     1462: 
1.1.1.4   root     1463:     if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
                   1464:         /* Pop and discard.  This is 2 bytes smaller than the add.  */
                   1465:         tcg_out_pop(s, TCG_REG_ECX);
                   1466:     } else if (stack_adjust != 0) {
1.1.1.5   root     1467:         tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
1.1       root     1468:     }
                   1469: 
                   1470:     /* label2: */
1.1.1.4   root     1471:     *label_ptr[2] = s->code_ptr - label_ptr[2] - 1;
                   1472: #else
                   1473:     {
                   1474:         int32_t offset = GUEST_BASE;
                   1475:         int base = args[addrlo_idx];
                   1476: 
                   1477:         if (TCG_TARGET_REG_BITS == 64) {
                   1478:             /* ??? We assume all operations have left us with register
                   1479:                contents that are zero extended.  So far this appears to
                   1480:                be true.  If we want to enforce this, we can either do
                   1481:                an explicit zero-extension here, or (if GUEST_BASE == 0)
                   1482:                use the ADDR32 prefix.  For now, do nothing.  */
                   1483: 
                   1484:             if (offset != GUEST_BASE) {
1.1.1.7 ! root     1485:                 tcg_out_movi(s, TCG_TYPE_I64,
        !          1486:                              tcg_target_call_iarg_regs[0], GUEST_BASE);
        !          1487:                 tgen_arithr(s, ARITH_ADD + P_REXW,
        !          1488:                             tcg_target_call_iarg_regs[0], base);
        !          1489:                 base = tcg_target_call_iarg_regs[0];
        !          1490:                 offset = 0;
1.1.1.4   root     1491:             }
                   1492:         }
                   1493: 
                   1494:         tcg_out_qemu_st_direct(s, data_reg, data_reg2, base, offset, opc);
                   1495:     }
1.1       root     1496: #endif
                   1497: }
                   1498: 
1.1.1.4   root     1499: static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1.1       root     1500:                               const TCGArg *args, const int *const_args)
                   1501: {
1.1.1.4   root     1502:     int c, rexw = 0;
                   1503: 
                   1504: #if TCG_TARGET_REG_BITS == 64
                   1505: # define OP_32_64(x) \
                   1506:         case glue(glue(INDEX_op_, x), _i64): \
                   1507:             rexw = P_REXW; /* FALLTHRU */    \
                   1508:         case glue(glue(INDEX_op_, x), _i32)
                   1509: #else
                   1510: # define OP_32_64(x) \
                   1511:         case glue(glue(INDEX_op_, x), _i32)
                   1512: #endif
                   1513: 
1.1       root     1514:     switch(opc) {
                   1515:     case INDEX_op_exit_tb:
1.1.1.4   root     1516:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]);
                   1517:         tcg_out_jmp(s, (tcg_target_long) tb_ret_addr);
1.1       root     1518:         break;
                   1519:     case INDEX_op_goto_tb:
                   1520:         if (s->tb_jmp_offset) {
                   1521:             /* direct jump method */
1.1.1.4   root     1522:             tcg_out8(s, OPC_JMP_long); /* jmp im */
1.1       root     1523:             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
                   1524:             tcg_out32(s, 0);
                   1525:         } else {
                   1526:             /* indirect jump method */
1.1.1.4   root     1527:             tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
1.1       root     1528:                                  (tcg_target_long)(s->tb_next + args[0]));
                   1529:         }
                   1530:         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
                   1531:         break;
                   1532:     case INDEX_op_call:
                   1533:         if (const_args[0]) {
1.1.1.4   root     1534:             tcg_out_calli(s, args[0]);
1.1       root     1535:         } else {
1.1.1.4   root     1536:             /* call *reg */
                   1537:             tcg_out_modrm(s, OPC_GRP5, EXT5_CALLN_Ev, args[0]);
1.1       root     1538:         }
                   1539:         break;
                   1540:     case INDEX_op_jmp:
                   1541:         if (const_args[0]) {
1.1.1.4   root     1542:             tcg_out_jmp(s, args[0]);
1.1       root     1543:         } else {
1.1.1.4   root     1544:             /* jmp *reg */
                   1545:             tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, args[0]);
1.1       root     1546:         }
                   1547:         break;
                   1548:     case INDEX_op_br:
1.1.1.4   root     1549:         tcg_out_jxx(s, JCC_JMP, args[0], 0);
1.1       root     1550:         break;
                   1551:     case INDEX_op_movi_i32:
                   1552:         tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
                   1553:         break;
1.1.1.4   root     1554:     OP_32_64(ld8u):
                   1555:         /* Note that we can ignore REXW for the zero-extend to 64-bit.  */
                   1556:         tcg_out_modrm_offset(s, OPC_MOVZBL, args[0], args[1], args[2]);
                   1557:         break;
                   1558:     OP_32_64(ld8s):
                   1559:         tcg_out_modrm_offset(s, OPC_MOVSBL + rexw, args[0], args[1], args[2]);
                   1560:         break;
                   1561:     OP_32_64(ld16u):
                   1562:         /* Note that we can ignore REXW for the zero-extend to 64-bit.  */
                   1563:         tcg_out_modrm_offset(s, OPC_MOVZWL, args[0], args[1], args[2]);
1.1       root     1564:         break;
1.1.1.4   root     1565:     OP_32_64(ld16s):
                   1566:         tcg_out_modrm_offset(s, OPC_MOVSWL + rexw, args[0], args[1], args[2]);
                   1567:         break;
                   1568: #if TCG_TARGET_REG_BITS == 64
                   1569:     case INDEX_op_ld32u_i64:
                   1570: #endif
1.1       root     1571:     case INDEX_op_ld_i32:
1.1.1.4   root     1572:         tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1.1       root     1573:         break;
1.1.1.4   root     1574: 
                   1575:     OP_32_64(st8):
                   1576:         tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
                   1577:                              args[0], args[1], args[2]);
1.1       root     1578:         break;
1.1.1.4   root     1579:     OP_32_64(st16):
                   1580:         tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
                   1581:                              args[0], args[1], args[2]);
1.1       root     1582:         break;
1.1.1.4   root     1583: #if TCG_TARGET_REG_BITS == 64
                   1584:     case INDEX_op_st32_i64:
                   1585: #endif
1.1       root     1586:     case INDEX_op_st_i32:
1.1.1.4   root     1587:         tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
1.1       root     1588:         break;
1.1.1.4   root     1589: 
                   1590:     OP_32_64(add):
                   1591:         /* For 3-operand addition, use LEA.  */
                   1592:         if (args[0] != args[1]) {
                   1593:             TCGArg a0 = args[0], a1 = args[1], a2 = args[2], c3 = 0;
                   1594: 
                   1595:             if (const_args[2]) {
                   1596:                 c3 = a2, a2 = -1;
                   1597:             } else if (a0 == a2) {
                   1598:                 /* Watch out for dest = src + dest, since we've removed
                   1599:                    the matching constraint on the add.  */
                   1600:                 tgen_arithr(s, ARITH_ADD + rexw, a0, a1);
                   1601:                 break;
                   1602:             }
                   1603: 
                   1604:             tcg_out_modrm_sib_offset(s, OPC_LEA + rexw, a0, a1, a2, 0, c3);
                   1605:             break;
                   1606:         }
                   1607:         c = ARITH_ADD;
                   1608:         goto gen_arith;
                   1609:     OP_32_64(sub):
1.1       root     1610:         c = ARITH_SUB;
                   1611:         goto gen_arith;
1.1.1.4   root     1612:     OP_32_64(and):
1.1       root     1613:         c = ARITH_AND;
                   1614:         goto gen_arith;
1.1.1.4   root     1615:     OP_32_64(or):
1.1       root     1616:         c = ARITH_OR;
                   1617:         goto gen_arith;
1.1.1.4   root     1618:     OP_32_64(xor):
1.1       root     1619:         c = ARITH_XOR;
                   1620:         goto gen_arith;
                   1621:     gen_arith:
                   1622:         if (const_args[2]) {
1.1.1.4   root     1623:             tgen_arithi(s, c + rexw, args[0], args[2], 0);
1.1       root     1624:         } else {
1.1.1.4   root     1625:             tgen_arithr(s, c + rexw, args[0], args[2]);
1.1       root     1626:         }
                   1627:         break;
1.1.1.4   root     1628: 
                   1629:     OP_32_64(mul):
1.1       root     1630:         if (const_args[2]) {
                   1631:             int32_t val;
                   1632:             val = args[2];
                   1633:             if (val == (int8_t)val) {
1.1.1.4   root     1634:                 tcg_out_modrm(s, OPC_IMUL_GvEvIb + rexw, args[0], args[0]);
1.1       root     1635:                 tcg_out8(s, val);
                   1636:             } else {
1.1.1.4   root     1637:                 tcg_out_modrm(s, OPC_IMUL_GvEvIz + rexw, args[0], args[0]);
1.1       root     1638:                 tcg_out32(s, val);
                   1639:             }
                   1640:         } else {
1.1.1.4   root     1641:             tcg_out_modrm(s, OPC_IMUL_GvEv + rexw, args[0], args[2]);
1.1       root     1642:         }
                   1643:         break;
1.1.1.4   root     1644: 
                   1645:     OP_32_64(div2):
                   1646:         tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_IDIV, args[4]);
1.1       root     1647:         break;
1.1.1.4   root     1648:     OP_32_64(divu2):
                   1649:         tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_DIV, args[4]);
1.1       root     1650:         break;
1.1.1.4   root     1651: 
                   1652:     OP_32_64(shl):
1.1       root     1653:         c = SHIFT_SHL;
1.1.1.4   root     1654:         goto gen_shift;
                   1655:     OP_32_64(shr):
1.1       root     1656:         c = SHIFT_SHR;
1.1.1.4   root     1657:         goto gen_shift;
                   1658:     OP_32_64(sar):
1.1       root     1659:         c = SHIFT_SAR;
1.1.1.4   root     1660:         goto gen_shift;
                   1661:     OP_32_64(rotl):
1.1.1.2   root     1662:         c = SHIFT_ROL;
1.1.1.4   root     1663:         goto gen_shift;
                   1664:     OP_32_64(rotr):
1.1.1.2   root     1665:         c = SHIFT_ROR;
1.1.1.4   root     1666:         goto gen_shift;
                   1667:     gen_shift:
                   1668:         if (const_args[2]) {
                   1669:             tcg_out_shifti(s, c + rexw, args[0], args[2]);
                   1670:         } else {
                   1671:             tcg_out_modrm(s, OPC_SHIFT_cl + rexw, c, args[0]);
                   1672:         }
1.1       root     1673:         break;
1.1.1.4   root     1674: 
1.1       root     1675:     case INDEX_op_brcond_i32:
1.1.1.4   root     1676:         tcg_out_brcond32(s, args[2], args[0], args[1], const_args[1],
                   1677:                          args[3], 0);
1.1       root     1678:         break;
1.1.1.4   root     1679:     case INDEX_op_setcond_i32:
                   1680:         tcg_out_setcond32(s, args[3], args[0], args[1],
                   1681:                           args[2], const_args[2]);
1.1       root     1682:         break;
                   1683: 
1.1.1.4   root     1684:     OP_32_64(bswap16):
                   1685:         tcg_out_rolw_8(s, args[0]);
1.1.1.2   root     1686:         break;
1.1.1.4   root     1687:     OP_32_64(bswap32):
                   1688:         tcg_out_bswap32(s, args[0]);
1.1.1.2   root     1689:         break;
                   1690: 
1.1.1.4   root     1691:     OP_32_64(neg):
                   1692:         tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NEG, args[0]);
1.1.1.2   root     1693:         break;
1.1.1.4   root     1694:     OP_32_64(not):
                   1695:         tcg_out_modrm(s, OPC_GRP3_Ev + rexw, EXT3_NOT, args[0]);
1.1.1.2   root     1696:         break;
                   1697: 
1.1.1.4   root     1698:     OP_32_64(ext8s):
                   1699:         tcg_out_ext8s(s, args[0], args[1], rexw);
1.1.1.2   root     1700:         break;
1.1.1.4   root     1701:     OP_32_64(ext16s):
                   1702:         tcg_out_ext16s(s, args[0], args[1], rexw);
1.1.1.2   root     1703:         break;
1.1.1.4   root     1704:     OP_32_64(ext8u):
                   1705:         tcg_out_ext8u(s, args[0], args[1]);
1.1.1.3   root     1706:         break;
1.1.1.4   root     1707:     OP_32_64(ext16u):
                   1708:         tcg_out_ext16u(s, args[0], args[1]);
1.1.1.3   root     1709:         break;
1.1.1.2   root     1710: 
1.1       root     1711:     case INDEX_op_qemu_ld8u:
                   1712:         tcg_out_qemu_ld(s, args, 0);
                   1713:         break;
                   1714:     case INDEX_op_qemu_ld8s:
                   1715:         tcg_out_qemu_ld(s, args, 0 | 4);
                   1716:         break;
                   1717:     case INDEX_op_qemu_ld16u:
                   1718:         tcg_out_qemu_ld(s, args, 1);
                   1719:         break;
                   1720:     case INDEX_op_qemu_ld16s:
                   1721:         tcg_out_qemu_ld(s, args, 1 | 4);
                   1722:         break;
1.1.1.4   root     1723: #if TCG_TARGET_REG_BITS == 64
1.1       root     1724:     case INDEX_op_qemu_ld32u:
1.1.1.4   root     1725: #endif
                   1726:     case INDEX_op_qemu_ld32:
1.1       root     1727:         tcg_out_qemu_ld(s, args, 2);
                   1728:         break;
                   1729:     case INDEX_op_qemu_ld64:
                   1730:         tcg_out_qemu_ld(s, args, 3);
                   1731:         break;
1.1.1.4   root     1732: 
1.1       root     1733:     case INDEX_op_qemu_st8:
                   1734:         tcg_out_qemu_st(s, args, 0);
                   1735:         break;
                   1736:     case INDEX_op_qemu_st16:
                   1737:         tcg_out_qemu_st(s, args, 1);
                   1738:         break;
                   1739:     case INDEX_op_qemu_st32:
                   1740:         tcg_out_qemu_st(s, args, 2);
                   1741:         break;
                   1742:     case INDEX_op_qemu_st64:
                   1743:         tcg_out_qemu_st(s, args, 3);
                   1744:         break;
                   1745: 
1.1.1.4   root     1746: #if TCG_TARGET_REG_BITS == 32
                   1747:     case INDEX_op_brcond2_i32:
                   1748:         tcg_out_brcond2(s, args, const_args, 0);
                   1749:         break;
                   1750:     case INDEX_op_setcond2_i32:
                   1751:         tcg_out_setcond2(s, args, const_args);
                   1752:         break;
                   1753:     case INDEX_op_mulu2_i32:
                   1754:         tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
                   1755:         break;
                   1756:     case INDEX_op_add2_i32:
                   1757:         if (const_args[4]) {
                   1758:             tgen_arithi(s, ARITH_ADD, args[0], args[4], 1);
                   1759:         } else {
                   1760:             tgen_arithr(s, ARITH_ADD, args[0], args[4]);
                   1761:         }
                   1762:         if (const_args[5]) {
                   1763:             tgen_arithi(s, ARITH_ADC, args[1], args[5], 1);
                   1764:         } else {
                   1765:             tgen_arithr(s, ARITH_ADC, args[1], args[5]);
                   1766:         }
                   1767:         break;
                   1768:     case INDEX_op_sub2_i32:
                   1769:         if (const_args[4]) {
                   1770:             tgen_arithi(s, ARITH_SUB, args[0], args[4], 1);
                   1771:         } else {
                   1772:             tgen_arithr(s, ARITH_SUB, args[0], args[4]);
                   1773:         }
                   1774:         if (const_args[5]) {
                   1775:             tgen_arithi(s, ARITH_SBB, args[1], args[5], 1);
                   1776:         } else {
                   1777:             tgen_arithr(s, ARITH_SBB, args[1], args[5]);
                   1778:         }
                   1779:         break;
                   1780: #else /* TCG_TARGET_REG_BITS == 64 */
                   1781:     case INDEX_op_movi_i64:
                   1782:         tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
                   1783:         break;
                   1784:     case INDEX_op_ld32s_i64:
                   1785:         tcg_out_modrm_offset(s, OPC_MOVSLQ, args[0], args[1], args[2]);
                   1786:         break;
                   1787:     case INDEX_op_ld_i64:
                   1788:         tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
                   1789:         break;
                   1790:     case INDEX_op_st_i64:
                   1791:         tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
                   1792:         break;
                   1793:     case INDEX_op_qemu_ld32s:
                   1794:         tcg_out_qemu_ld(s, args, 2 | 4);
                   1795:         break;
                   1796: 
                   1797:     case INDEX_op_brcond_i64:
                   1798:         tcg_out_brcond64(s, args[2], args[0], args[1], const_args[1],
                   1799:                          args[3], 0);
                   1800:         break;
                   1801:     case INDEX_op_setcond_i64:
                   1802:         tcg_out_setcond64(s, args[3], args[0], args[1],
                   1803:                           args[2], const_args[2]);
                   1804:         break;
                   1805: 
                   1806:     case INDEX_op_bswap64_i64:
                   1807:         tcg_out_bswap64(s, args[0]);
                   1808:         break;
                   1809:     case INDEX_op_ext32u_i64:
                   1810:         tcg_out_ext32u(s, args[0], args[1]);
                   1811:         break;
                   1812:     case INDEX_op_ext32s_i64:
                   1813:         tcg_out_ext32s(s, args[0], args[1]);
                   1814:         break;
                   1815: #endif
                   1816: 
1.1.1.6   root     1817:     OP_32_64(deposit):
                   1818:         if (args[3] == 0 && args[4] == 8) {
                   1819:             /* load bits 0..7 */
                   1820:             tcg_out_modrm(s, OPC_MOVB_EvGv | P_REXB_R | P_REXB_RM,
                   1821:                           args[2], args[0]);
                   1822:         } else if (args[3] == 8 && args[4] == 8) {
                   1823:             /* load bits 8..15 */
                   1824:             tcg_out_modrm(s, OPC_MOVB_EvGv, args[2], args[0] + 4);
                   1825:         } else if (args[3] == 0 && args[4] == 16) {
                   1826:             /* load bits 0..15 */
                   1827:             tcg_out_modrm(s, OPC_MOVL_EvGv | P_DATA16, args[2], args[0]);
                   1828:         } else {
                   1829:             tcg_abort();
                   1830:         }
                   1831:         break;
                   1832: 
1.1       root     1833:     default:
                   1834:         tcg_abort();
                   1835:     }
1.1.1.4   root     1836: 
                   1837: #undef OP_32_64
1.1       root     1838: }
                   1839: 
                   1840: static const TCGTargetOpDef x86_op_defs[] = {
                   1841:     { INDEX_op_exit_tb, { } },
                   1842:     { INDEX_op_goto_tb, { } },
                   1843:     { INDEX_op_call, { "ri" } },
                   1844:     { INDEX_op_jmp, { "ri" } },
                   1845:     { INDEX_op_br, { } },
                   1846:     { INDEX_op_mov_i32, { "r", "r" } },
                   1847:     { INDEX_op_movi_i32, { "r" } },
                   1848:     { INDEX_op_ld8u_i32, { "r", "r" } },
                   1849:     { INDEX_op_ld8s_i32, { "r", "r" } },
                   1850:     { INDEX_op_ld16u_i32, { "r", "r" } },
                   1851:     { INDEX_op_ld16s_i32, { "r", "r" } },
                   1852:     { INDEX_op_ld_i32, { "r", "r" } },
                   1853:     { INDEX_op_st8_i32, { "q", "r" } },
                   1854:     { INDEX_op_st16_i32, { "r", "r" } },
                   1855:     { INDEX_op_st_i32, { "r", "r" } },
                   1856: 
1.1.1.4   root     1857:     { INDEX_op_add_i32, { "r", "r", "ri" } },
1.1       root     1858:     { INDEX_op_sub_i32, { "r", "0", "ri" } },
                   1859:     { INDEX_op_mul_i32, { "r", "0", "ri" } },
                   1860:     { INDEX_op_div2_i32, { "a", "d", "0", "1", "r" } },
                   1861:     { INDEX_op_divu2_i32, { "a", "d", "0", "1", "r" } },
                   1862:     { INDEX_op_and_i32, { "r", "0", "ri" } },
                   1863:     { INDEX_op_or_i32, { "r", "0", "ri" } },
                   1864:     { INDEX_op_xor_i32, { "r", "0", "ri" } },
                   1865: 
                   1866:     { INDEX_op_shl_i32, { "r", "0", "ci" } },
                   1867:     { INDEX_op_shr_i32, { "r", "0", "ci" } },
                   1868:     { INDEX_op_sar_i32, { "r", "0", "ci" } },
1.1.1.2   root     1869:     { INDEX_op_rotl_i32, { "r", "0", "ci" } },
                   1870:     { INDEX_op_rotr_i32, { "r", "0", "ci" } },
1.1       root     1871: 
                   1872:     { INDEX_op_brcond_i32, { "r", "ri" } },
                   1873: 
1.1.1.2   root     1874:     { INDEX_op_bswap16_i32, { "r", "0" } },
                   1875:     { INDEX_op_bswap32_i32, { "r", "0" } },
                   1876: 
                   1877:     { INDEX_op_neg_i32, { "r", "0" } },
                   1878: 
                   1879:     { INDEX_op_not_i32, { "r", "0" } },
                   1880: 
                   1881:     { INDEX_op_ext8s_i32, { "r", "q" } },
                   1882:     { INDEX_op_ext16s_i32, { "r", "r" } },
1.1.1.4   root     1883:     { INDEX_op_ext8u_i32, { "r", "q" } },
                   1884:     { INDEX_op_ext16u_i32, { "r", "r" } },
                   1885: 
                   1886:     { INDEX_op_setcond_i32, { "q", "r", "ri" } },
                   1887: 
1.1.1.6   root     1888:     { INDEX_op_deposit_i32, { "Q", "0", "Q" } },
                   1889: 
1.1.1.4   root     1890: #if TCG_TARGET_REG_BITS == 32
                   1891:     { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
                   1892:     { INDEX_op_add2_i32, { "r", "r", "0", "1", "ri", "ri" } },
                   1893:     { INDEX_op_sub2_i32, { "r", "r", "0", "1", "ri", "ri" } },
                   1894:     { INDEX_op_brcond2_i32, { "r", "r", "ri", "ri" } },
                   1895:     { INDEX_op_setcond2_i32, { "r", "r", "r", "ri", "ri" } },
                   1896: #else
                   1897:     { INDEX_op_mov_i64, { "r", "r" } },
                   1898:     { INDEX_op_movi_i64, { "r" } },
                   1899:     { INDEX_op_ld8u_i64, { "r", "r" } },
                   1900:     { INDEX_op_ld8s_i64, { "r", "r" } },
                   1901:     { INDEX_op_ld16u_i64, { "r", "r" } },
                   1902:     { INDEX_op_ld16s_i64, { "r", "r" } },
                   1903:     { INDEX_op_ld32u_i64, { "r", "r" } },
                   1904:     { INDEX_op_ld32s_i64, { "r", "r" } },
                   1905:     { INDEX_op_ld_i64, { "r", "r" } },
                   1906:     { INDEX_op_st8_i64, { "r", "r" } },
                   1907:     { INDEX_op_st16_i64, { "r", "r" } },
                   1908:     { INDEX_op_st32_i64, { "r", "r" } },
                   1909:     { INDEX_op_st_i64, { "r", "r" } },
                   1910: 
                   1911:     { INDEX_op_add_i64, { "r", "0", "re" } },
                   1912:     { INDEX_op_mul_i64, { "r", "0", "re" } },
                   1913:     { INDEX_op_div2_i64, { "a", "d", "0", "1", "r" } },
                   1914:     { INDEX_op_divu2_i64, { "a", "d", "0", "1", "r" } },
                   1915:     { INDEX_op_sub_i64, { "r", "0", "re" } },
                   1916:     { INDEX_op_and_i64, { "r", "0", "reZ" } },
                   1917:     { INDEX_op_or_i64, { "r", "0", "re" } },
                   1918:     { INDEX_op_xor_i64, { "r", "0", "re" } },
                   1919: 
                   1920:     { INDEX_op_shl_i64, { "r", "0", "ci" } },
                   1921:     { INDEX_op_shr_i64, { "r", "0", "ci" } },
                   1922:     { INDEX_op_sar_i64, { "r", "0", "ci" } },
                   1923:     { INDEX_op_rotl_i64, { "r", "0", "ci" } },
                   1924:     { INDEX_op_rotr_i64, { "r", "0", "ci" } },
                   1925: 
                   1926:     { INDEX_op_brcond_i64, { "r", "re" } },
                   1927:     { INDEX_op_setcond_i64, { "r", "r", "re" } },
                   1928: 
                   1929:     { INDEX_op_bswap16_i64, { "r", "0" } },
                   1930:     { INDEX_op_bswap32_i64, { "r", "0" } },
                   1931:     { INDEX_op_bswap64_i64, { "r", "0" } },
                   1932:     { INDEX_op_neg_i64, { "r", "0" } },
                   1933:     { INDEX_op_not_i64, { "r", "0" } },
                   1934: 
                   1935:     { INDEX_op_ext8s_i64, { "r", "r" } },
                   1936:     { INDEX_op_ext16s_i64, { "r", "r" } },
                   1937:     { INDEX_op_ext32s_i64, { "r", "r" } },
                   1938:     { INDEX_op_ext8u_i64, { "r", "r" } },
                   1939:     { INDEX_op_ext16u_i64, { "r", "r" } },
                   1940:     { INDEX_op_ext32u_i64, { "r", "r" } },
1.1.1.6   root     1941: 
                   1942:     { INDEX_op_deposit_i64, { "Q", "0", "Q" } },
1.1.1.4   root     1943: #endif
1.1.1.2   root     1944: 
1.1.1.4   root     1945: #if TCG_TARGET_REG_BITS == 64
1.1       root     1946:     { INDEX_op_qemu_ld8u, { "r", "L" } },
                   1947:     { INDEX_op_qemu_ld8s, { "r", "L" } },
                   1948:     { INDEX_op_qemu_ld16u, { "r", "L" } },
                   1949:     { INDEX_op_qemu_ld16s, { "r", "L" } },
1.1.1.4   root     1950:     { INDEX_op_qemu_ld32, { "r", "L" } },
1.1       root     1951:     { INDEX_op_qemu_ld32u, { "r", "L" } },
1.1.1.4   root     1952:     { INDEX_op_qemu_ld32s, { "r", "L" } },
                   1953:     { INDEX_op_qemu_ld64, { "r", "L" } },
                   1954: 
                   1955:     { INDEX_op_qemu_st8, { "L", "L" } },
                   1956:     { INDEX_op_qemu_st16, { "L", "L" } },
                   1957:     { INDEX_op_qemu_st32, { "L", "L" } },
                   1958:     { INDEX_op_qemu_st64, { "L", "L" } },
                   1959: #elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
                   1960:     { INDEX_op_qemu_ld8u, { "r", "L" } },
                   1961:     { INDEX_op_qemu_ld8s, { "r", "L" } },
                   1962:     { INDEX_op_qemu_ld16u, { "r", "L" } },
                   1963:     { INDEX_op_qemu_ld16s, { "r", "L" } },
                   1964:     { INDEX_op_qemu_ld32, { "r", "L" } },
1.1       root     1965:     { INDEX_op_qemu_ld64, { "r", "r", "L" } },
                   1966: 
                   1967:     { INDEX_op_qemu_st8, { "cb", "L" } },
                   1968:     { INDEX_op_qemu_st16, { "L", "L" } },
                   1969:     { INDEX_op_qemu_st32, { "L", "L" } },
                   1970:     { INDEX_op_qemu_st64, { "L", "L", "L" } },
                   1971: #else
                   1972:     { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
                   1973:     { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
                   1974:     { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
                   1975:     { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
1.1.1.4   root     1976:     { INDEX_op_qemu_ld32, { "r", "L", "L" } },
1.1       root     1977:     { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
                   1978: 
                   1979:     { INDEX_op_qemu_st8, { "cb", "L", "L" } },
                   1980:     { INDEX_op_qemu_st16, { "L", "L", "L" } },
                   1981:     { INDEX_op_qemu_st32, { "L", "L", "L" } },
                   1982:     { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
                   1983: #endif
                   1984:     { -1 },
                   1985: };
                   1986: 
                   1987: static int tcg_target_callee_save_regs[] = {
1.1.1.4   root     1988: #if TCG_TARGET_REG_BITS == 64
                   1989:     TCG_REG_RBP,
                   1990:     TCG_REG_RBX,
1.1.1.7 ! root     1991: #if defined(_WIN64)
        !          1992:     TCG_REG_RDI,
        !          1993:     TCG_REG_RSI,
        !          1994: #endif
1.1.1.4   root     1995:     TCG_REG_R12,
                   1996:     TCG_REG_R13,
1.1.1.5   root     1997:     TCG_REG_R14, /* Currently used for the global env. */
1.1.1.4   root     1998:     TCG_REG_R15,
                   1999: #else
1.1.1.5   root     2000:     TCG_REG_EBP, /* Currently used for the global env. */
1.1       root     2001:     TCG_REG_EBX,
                   2002:     TCG_REG_ESI,
                   2003:     TCG_REG_EDI,
1.1.1.4   root     2004: #endif
1.1       root     2005: };
                   2006: 
1.1.1.7 ! root     2007: /* Compute frame size via macros, to share between tcg_target_qemu_prologue
        !          2008:    and tcg_register_jit.  */
        !          2009: 
        !          2010: #define PUSH_SIZE \
        !          2011:     ((1 + ARRAY_SIZE(tcg_target_callee_save_regs)) \
        !          2012:      * (TCG_TARGET_REG_BITS / 8))
        !          2013: 
        !          2014: #define FRAME_SIZE \
        !          2015:     ((PUSH_SIZE \
        !          2016:       + TCG_STATIC_CALL_ARGS_SIZE \
        !          2017:       + CPU_TEMP_BUF_NLONGS * sizeof(long) \
        !          2018:       + TCG_TARGET_STACK_ALIGN - 1) \
        !          2019:      & ~(TCG_TARGET_STACK_ALIGN - 1))
        !          2020: 
1.1       root     2021: /* Generate global QEMU prologue and epilogue code */
1.1.1.4   root     2022: static void tcg_target_qemu_prologue(TCGContext *s)
1.1       root     2023: {
1.1.1.7 ! root     2024:     int i, stack_addend;
1.1.1.4   root     2025: 
1.1       root     2026:     /* TB prologue */
1.1.1.4   root     2027: 
1.1.1.5   root     2028:     /* Reserve some stack space, also for TCG temps.  */
1.1.1.7 ! root     2029:     stack_addend = FRAME_SIZE - PUSH_SIZE;
1.1.1.5   root     2030:     tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
                   2031:                   CPU_TEMP_BUF_NLONGS * sizeof(long));
                   2032: 
                   2033:     /* Save all callee saved registers.  */
                   2034:     for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
                   2035:         tcg_out_push(s, tcg_target_callee_save_regs[i]);
                   2036:     }
                   2037: 
1.1.1.7 ! root     2038: #if TCG_TARGET_REG_BITS == 32
        !          2039:     tcg_out_ld(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP,
        !          2040:                (ARRAY_SIZE(tcg_target_callee_save_regs) + 1) * 4);
        !          2041:     tcg_out_ld(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[1], TCG_REG_ESP,
        !          2042:                (ARRAY_SIZE(tcg_target_callee_save_regs) + 2) * 4);
        !          2043: #else
1.1.1.5   root     2044:     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
1.1.1.7 ! root     2045: #endif
        !          2046:     tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
1.1.1.5   root     2047: 
1.1.1.4   root     2048:     /* jmp *tb.  */
1.1.1.5   root     2049:     tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);
1.1.1.4   root     2050: 
1.1       root     2051:     /* TB epilogue */
                   2052:     tb_ret_addr = s->code_ptr;
1.1.1.4   root     2053: 
1.1.1.5   root     2054:     tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend);
1.1.1.4   root     2055: 
                   2056:     for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
1.1       root     2057:         tcg_out_pop(s, tcg_target_callee_save_regs[i]);
                   2058:     }
1.1.1.4   root     2059:     tcg_out_opc(s, OPC_RET, 0, 0, 0);
1.1       root     2060: }
                   2061: 
1.1.1.4   root     2062: static void tcg_target_init(TCGContext *s)
1.1       root     2063: {
1.1.1.4   root     2064: #if !defined(CONFIG_USER_ONLY)
1.1       root     2065:     /* fail safe */
                   2066:     if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry))
                   2067:         tcg_abort();
1.1.1.4   root     2068: #endif
                   2069: 
                   2070:     if (TCG_TARGET_REG_BITS == 64) {
                   2071:         tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
                   2072:         tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
                   2073:     } else {
                   2074:         tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xff);
                   2075:     }
                   2076: 
                   2077:     tcg_regset_clear(tcg_target_call_clobber_regs);
                   2078:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EAX);
                   2079:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
                   2080:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
                   2081:     if (TCG_TARGET_REG_BITS == 64) {
1.1.1.7 ! root     2082: #if !defined(_WIN64)
1.1.1.4   root     2083:         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI);
                   2084:         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI);
1.1.1.7 ! root     2085: #endif
1.1.1.4   root     2086:         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
                   2087:         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
                   2088:         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
                   2089:         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R11);
                   2090:     }
1.1       root     2091: 
                   2092:     tcg_regset_clear(s->reserved_regs);
1.1.1.5   root     2093:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
1.1       root     2094: 
                   2095:     tcg_add_target_add_op_defs(x86_op_defs);
                   2096: }
1.1.1.7 ! root     2097: 
        !          2098: typedef struct {
        !          2099:     uint32_t len __attribute__((aligned((sizeof(void *)))));
        !          2100:     uint32_t id;
        !          2101:     uint8_t version;
        !          2102:     char augmentation[1];
        !          2103:     uint8_t code_align;
        !          2104:     uint8_t data_align;
        !          2105:     uint8_t return_column;
        !          2106: } DebugFrameCIE;
        !          2107: 
        !          2108: typedef struct {
        !          2109:     uint32_t len __attribute__((aligned((sizeof(void *)))));
        !          2110:     uint32_t cie_offset;
        !          2111:     tcg_target_long func_start __attribute__((packed));
        !          2112:     tcg_target_long func_len __attribute__((packed));
        !          2113:     uint8_t def_cfa[4];
        !          2114:     uint8_t reg_ofs[14];
        !          2115: } DebugFrameFDE;
        !          2116: 
        !          2117: typedef struct {
        !          2118:     DebugFrameCIE cie;
        !          2119:     DebugFrameFDE fde;
        !          2120: } DebugFrame;
        !          2121: 
        !          2122: #if !defined(__ELF__)
        !          2123:     /* Host machine without ELF. */
        !          2124: #elif TCG_TARGET_REG_BITS == 64
        !          2125: #define ELF_HOST_MACHINE EM_X86_64
        !          2126: static DebugFrame debug_frame = {
        !          2127:     .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
        !          2128:     .cie.id = -1,
        !          2129:     .cie.version = 1,
        !          2130:     .cie.code_align = 1,
        !          2131:     .cie.data_align = 0x78,             /* sleb128 -8 */
        !          2132:     .cie.return_column = 16,
        !          2133: 
        !          2134:     .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
        !          2135:     .fde.def_cfa = {
        !          2136:         12, 7,                          /* DW_CFA_def_cfa %rsp, ... */
        !          2137:         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
        !          2138:         (FRAME_SIZE >> 7)
        !          2139:     },
        !          2140:     .fde.reg_ofs = {
        !          2141:         0x90, 1,                        /* DW_CFA_offset, %rip, -8 */
        !          2142:         /* The following ordering must match tcg_target_callee_save_regs.  */
        !          2143:         0x86, 2,                        /* DW_CFA_offset, %rbp, -16 */
        !          2144:         0x83, 3,                        /* DW_CFA_offset, %rbx, -24 */
        !          2145:         0x8c, 4,                        /* DW_CFA_offset, %r12, -32 */
        !          2146:         0x8d, 5,                        /* DW_CFA_offset, %r13, -40 */
        !          2147:         0x8e, 6,                        /* DW_CFA_offset, %r14, -48 */
        !          2148:         0x8f, 7,                        /* DW_CFA_offset, %r15, -56 */
        !          2149:     }
        !          2150: };
        !          2151: #else
        !          2152: #define ELF_HOST_MACHINE EM_386
        !          2153: static DebugFrame debug_frame = {
        !          2154:     .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
        !          2155:     .cie.id = -1,
        !          2156:     .cie.version = 1,
        !          2157:     .cie.code_align = 1,
        !          2158:     .cie.data_align = 0x7c,             /* sleb128 -4 */
        !          2159:     .cie.return_column = 8,
        !          2160: 
        !          2161:     .fde.len = sizeof(DebugFrameFDE)-4, /* length after .len member */
        !          2162:     .fde.def_cfa = {
        !          2163:         12, 4,                          /* DW_CFA_def_cfa %esp, ... */
        !          2164:         (FRAME_SIZE & 0x7f) | 0x80,     /* ... uleb128 FRAME_SIZE */
        !          2165:         (FRAME_SIZE >> 7)
        !          2166:     },
        !          2167:     .fde.reg_ofs = {
        !          2168:         0x88, 1,                        /* DW_CFA_offset, %eip, -4 */
        !          2169:         /* The following ordering must match tcg_target_callee_save_regs.  */
        !          2170:         0x85, 2,                        /* DW_CFA_offset, %ebp, -8 */
        !          2171:         0x83, 3,                        /* DW_CFA_offset, %ebx, -12 */
        !          2172:         0x86, 4,                        /* DW_CFA_offset, %esi, -16 */
        !          2173:         0x87, 5,                        /* DW_CFA_offset, %edi, -20 */
        !          2174:     }
        !          2175: };
        !          2176: #endif
        !          2177: 
        !          2178: #if defined(ELF_HOST_MACHINE)
        !          2179: void tcg_register_jit(void *buf, size_t buf_size)
        !          2180: {
        !          2181:     /* We're expecting a 2 byte uleb128 encoded value.  */
        !          2182:     assert(FRAME_SIZE >> 14 == 0);
        !          2183: 
        !          2184:     debug_frame.fde.func_start = (tcg_target_long) buf;
        !          2185:     debug_frame.fde.func_len = buf_size;
        !          2186: 
        !          2187:     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
        !          2188: }
        !          2189: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.