Annotation of qemu/tcg/tci/tcg-target.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * Tiny Code Generator for QEMU
                      3:  *
                      4:  * Copyright (c) 2009, 2011 Stefan Weil
                      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: /* TODO list:
                     26:  * - See TODO comments in code.
                     27:  */
                     28: 
                     29: /* Marker for missing code. */
                     30: #define TODO() \
                     31:     do { \
                     32:         fprintf(stderr, "TODO %s:%u: %s()\n", \
                     33:                 __FILE__, __LINE__, __func__); \
                     34:         tcg_abort(); \
                     35:     } while (0)
                     36: 
                     37: /* Single bit n. */
                     38: #define BIT(n) (1 << (n))
                     39: 
                     40: /* Bitfield n...m (in 32 bit value). */
                     41: #define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
                     42: 
                     43: /* Used for function call generation. */
                     44: #define TCG_REG_CALL_STACK              TCG_REG_R4
                     45: #define TCG_TARGET_STACK_ALIGN          16
                     46: #define TCG_TARGET_CALL_STACK_OFFSET    0
                     47: 
                     48: /* TODO: documentation. */
                     49: static uint8_t *tb_ret_addr;
                     50: 
                     51: /* Macros used in tcg_target_op_defs. */
                     52: #define R       "r"
                     53: #define RI      "ri"
                     54: #if TCG_TARGET_REG_BITS == 32
                     55: # define R64    "r", "r"
                     56: #else
                     57: # define R64    "r"
                     58: #endif
                     59: #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
                     60: # define L      "L", "L"
                     61: # define S      "S", "S"
                     62: #else
                     63: # define L      "L"
                     64: # define S      "S"
                     65: #endif
                     66: 
                     67: /* TODO: documentation. */
                     68: static const TCGTargetOpDef tcg_target_op_defs[] = {
                     69:     { INDEX_op_exit_tb, { NULL } },
                     70:     { INDEX_op_goto_tb, { NULL } },
                     71:     { INDEX_op_call, { RI } },
                     72:     { INDEX_op_jmp, { RI } },
                     73:     { INDEX_op_br, { NULL } },
                     74: 
                     75:     { INDEX_op_mov_i32, { R, R } },
                     76:     { INDEX_op_movi_i32, { R } },
                     77: 
                     78:     { INDEX_op_ld8u_i32, { R, R } },
                     79:     { INDEX_op_ld8s_i32, { R, R } },
                     80:     { INDEX_op_ld16u_i32, { R, R } },
                     81:     { INDEX_op_ld16s_i32, { R, R } },
                     82:     { INDEX_op_ld_i32, { R, R } },
                     83:     { INDEX_op_st8_i32, { R, R } },
                     84:     { INDEX_op_st16_i32, { R, R } },
                     85:     { INDEX_op_st_i32, { R, R } },
                     86: 
                     87:     { INDEX_op_add_i32, { R, RI, RI } },
                     88:     { INDEX_op_sub_i32, { R, RI, RI } },
                     89:     { INDEX_op_mul_i32, { R, RI, RI } },
                     90: #if TCG_TARGET_HAS_div_i32
                     91:     { INDEX_op_div_i32, { R, R, R } },
                     92:     { INDEX_op_divu_i32, { R, R, R } },
                     93:     { INDEX_op_rem_i32, { R, R, R } },
                     94:     { INDEX_op_remu_i32, { R, R, R } },
                     95: #elif TCG_TARGET_HAS_div2_i32
                     96:     { INDEX_op_div2_i32, { R, R, "0", "1", R } },
                     97:     { INDEX_op_divu2_i32, { R, R, "0", "1", R } },
                     98: #endif
                     99:     /* TODO: Does R, RI, RI result in faster code than R, R, RI?
                    100:        If both operands are constants, we can optimize. */
                    101:     { INDEX_op_and_i32, { R, RI, RI } },
                    102: #if TCG_TARGET_HAS_andc_i32
                    103:     { INDEX_op_andc_i32, { R, RI, RI } },
                    104: #endif
                    105: #if TCG_TARGET_HAS_eqv_i32
                    106:     { INDEX_op_eqv_i32, { R, RI, RI } },
                    107: #endif
                    108: #if TCG_TARGET_HAS_nand_i32
                    109:     { INDEX_op_nand_i32, { R, RI, RI } },
                    110: #endif
                    111: #if TCG_TARGET_HAS_nor_i32
                    112:     { INDEX_op_nor_i32, { R, RI, RI } },
                    113: #endif
                    114:     { INDEX_op_or_i32, { R, RI, RI } },
                    115: #if TCG_TARGET_HAS_orc_i32
                    116:     { INDEX_op_orc_i32, { R, RI, RI } },
                    117: #endif
                    118:     { INDEX_op_xor_i32, { R, RI, RI } },
                    119:     { INDEX_op_shl_i32, { R, RI, RI } },
                    120:     { INDEX_op_shr_i32, { R, RI, RI } },
                    121:     { INDEX_op_sar_i32, { R, RI, RI } },
                    122: #if TCG_TARGET_HAS_rot_i32
                    123:     { INDEX_op_rotl_i32, { R, RI, RI } },
                    124:     { INDEX_op_rotr_i32, { R, RI, RI } },
                    125: #endif
                    126: 
                    127:     { INDEX_op_brcond_i32, { R, RI } },
                    128: 
                    129:     { INDEX_op_setcond_i32, { R, R, RI } },
                    130: #if TCG_TARGET_REG_BITS == 64
                    131:     { INDEX_op_setcond_i64, { R, R, RI } },
                    132: #endif /* TCG_TARGET_REG_BITS == 64 */
                    133: 
                    134: #if TCG_TARGET_REG_BITS == 32
                    135:     /* TODO: Support R, R, R, R, RI, RI? Will it be faster? */
                    136:     { INDEX_op_add2_i32, { R, R, R, R, R, R } },
                    137:     { INDEX_op_sub2_i32, { R, R, R, R, R, R } },
                    138:     { INDEX_op_brcond2_i32, { R, R, RI, RI } },
                    139:     { INDEX_op_mulu2_i32, { R, R, R, R } },
                    140:     { INDEX_op_setcond2_i32, { R, R, R, RI, RI } },
                    141: #endif
                    142: 
                    143: #if TCG_TARGET_HAS_not_i32
                    144:     { INDEX_op_not_i32, { R, R } },
                    145: #endif
                    146: #if TCG_TARGET_HAS_neg_i32
                    147:     { INDEX_op_neg_i32, { R, R } },
                    148: #endif
                    149: 
                    150: #if TCG_TARGET_REG_BITS == 64
                    151:     { INDEX_op_mov_i64, { R, R } },
                    152:     { INDEX_op_movi_i64, { R } },
                    153: 
                    154:     { INDEX_op_ld8u_i64, { R, R } },
                    155:     { INDEX_op_ld8s_i64, { R, R } },
                    156:     { INDEX_op_ld16u_i64, { R, R } },
                    157:     { INDEX_op_ld16s_i64, { R, R } },
                    158:     { INDEX_op_ld32u_i64, { R, R } },
                    159:     { INDEX_op_ld32s_i64, { R, R } },
                    160:     { INDEX_op_ld_i64, { R, R } },
                    161: 
                    162:     { INDEX_op_st8_i64, { R, R } },
                    163:     { INDEX_op_st16_i64, { R, R } },
                    164:     { INDEX_op_st32_i64, { R, R } },
                    165:     { INDEX_op_st_i64, { R, R } },
                    166: 
                    167:     { INDEX_op_add_i64, { R, RI, RI } },
                    168:     { INDEX_op_sub_i64, { R, RI, RI } },
                    169:     { INDEX_op_mul_i64, { R, RI, RI } },
                    170: #if TCG_TARGET_HAS_div_i64
                    171:     { INDEX_op_div_i64, { R, R, R } },
                    172:     { INDEX_op_divu_i64, { R, R, R } },
                    173:     { INDEX_op_rem_i64, { R, R, R } },
                    174:     { INDEX_op_remu_i64, { R, R, R } },
                    175: #elif TCG_TARGET_HAS_div2_i64
                    176:     { INDEX_op_div2_i64, { R, R, "0", "1", R } },
                    177:     { INDEX_op_divu2_i64, { R, R, "0", "1", R } },
                    178: #endif
                    179:     { INDEX_op_and_i64, { R, RI, RI } },
                    180: #if TCG_TARGET_HAS_andc_i64
                    181:     { INDEX_op_andc_i64, { R, RI, RI } },
                    182: #endif
                    183: #if TCG_TARGET_HAS_eqv_i64
                    184:     { INDEX_op_eqv_i64, { R, RI, RI } },
                    185: #endif
                    186: #if TCG_TARGET_HAS_nand_i64
                    187:     { INDEX_op_nand_i64, { R, RI, RI } },
                    188: #endif
                    189: #if TCG_TARGET_HAS_nor_i64
                    190:     { INDEX_op_nor_i64, { R, RI, RI } },
                    191: #endif
                    192:     { INDEX_op_or_i64, { R, RI, RI } },
                    193: #if TCG_TARGET_HAS_orc_i64
                    194:     { INDEX_op_orc_i64, { R, RI, RI } },
                    195: #endif
                    196:     { INDEX_op_xor_i64, { R, RI, RI } },
                    197:     { INDEX_op_shl_i64, { R, RI, RI } },
                    198:     { INDEX_op_shr_i64, { R, RI, RI } },
                    199:     { INDEX_op_sar_i64, { R, RI, RI } },
                    200: #if TCG_TARGET_HAS_rot_i64
                    201:     { INDEX_op_rotl_i64, { R, RI, RI } },
                    202:     { INDEX_op_rotr_i64, { R, RI, RI } },
                    203: #endif
                    204:     { INDEX_op_brcond_i64, { R, RI } },
                    205: 
                    206: #if TCG_TARGET_HAS_ext8s_i64
                    207:     { INDEX_op_ext8s_i64, { R, R } },
                    208: #endif
                    209: #if TCG_TARGET_HAS_ext16s_i64
                    210:     { INDEX_op_ext16s_i64, { R, R } },
                    211: #endif
                    212: #if TCG_TARGET_HAS_ext32s_i64
                    213:     { INDEX_op_ext32s_i64, { R, R } },
                    214: #endif
                    215: #if TCG_TARGET_HAS_ext8u_i64
                    216:     { INDEX_op_ext8u_i64, { R, R } },
                    217: #endif
                    218: #if TCG_TARGET_HAS_ext16u_i64
                    219:     { INDEX_op_ext16u_i64, { R, R } },
                    220: #endif
                    221: #if TCG_TARGET_HAS_ext32u_i64
                    222:     { INDEX_op_ext32u_i64, { R, R } },
                    223: #endif
                    224: #if TCG_TARGET_HAS_bswap16_i64
                    225:     { INDEX_op_bswap16_i64, { R, R } },
                    226: #endif
                    227: #if TCG_TARGET_HAS_bswap32_i64
                    228:     { INDEX_op_bswap32_i64, { R, R } },
                    229: #endif
                    230: #if TCG_TARGET_HAS_bswap64_i64
                    231:     { INDEX_op_bswap64_i64, { R, R } },
                    232: #endif
                    233: #if TCG_TARGET_HAS_not_i64
                    234:     { INDEX_op_not_i64, { R, R } },
                    235: #endif
                    236: #if TCG_TARGET_HAS_neg_i64
                    237:     { INDEX_op_neg_i64, { R, R } },
                    238: #endif
                    239: #endif /* TCG_TARGET_REG_BITS == 64 */
                    240: 
                    241:     { INDEX_op_qemu_ld8u, { R, L } },
                    242:     { INDEX_op_qemu_ld8s, { R, L } },
                    243:     { INDEX_op_qemu_ld16u, { R, L } },
                    244:     { INDEX_op_qemu_ld16s, { R, L } },
                    245:     { INDEX_op_qemu_ld32, { R, L } },
                    246: #if TCG_TARGET_REG_BITS == 64
                    247:     { INDEX_op_qemu_ld32u, { R, L } },
                    248:     { INDEX_op_qemu_ld32s, { R, L } },
                    249: #endif
                    250:     { INDEX_op_qemu_ld64, { R64, L } },
                    251: 
                    252:     { INDEX_op_qemu_st8, { R, S } },
                    253:     { INDEX_op_qemu_st16, { R, S } },
                    254:     { INDEX_op_qemu_st32, { R, S } },
                    255:     { INDEX_op_qemu_st64, { R64, S } },
                    256: 
                    257: #if TCG_TARGET_HAS_ext8s_i32
                    258:     { INDEX_op_ext8s_i32, { R, R } },
                    259: #endif
                    260: #if TCG_TARGET_HAS_ext16s_i32
                    261:     { INDEX_op_ext16s_i32, { R, R } },
                    262: #endif
                    263: #if TCG_TARGET_HAS_ext8u_i32
                    264:     { INDEX_op_ext8u_i32, { R, R } },
                    265: #endif
                    266: #if TCG_TARGET_HAS_ext16u_i32
                    267:     { INDEX_op_ext16u_i32, { R, R } },
                    268: #endif
                    269: 
                    270: #if TCG_TARGET_HAS_bswap16_i32
                    271:     { INDEX_op_bswap16_i32, { R, R } },
                    272: #endif
                    273: #if TCG_TARGET_HAS_bswap32_i32
                    274:     { INDEX_op_bswap32_i32, { R, R } },
                    275: #endif
                    276: 
                    277:     { -1 },
                    278: };
                    279: 
                    280: static const int tcg_target_reg_alloc_order[] = {
                    281:     TCG_REG_R0,
                    282:     TCG_REG_R1,
                    283:     TCG_REG_R2,
                    284:     TCG_REG_R3,
                    285: #if 0 /* used for TCG_REG_CALL_STACK */
                    286:     TCG_REG_R4,
                    287: #endif
                    288:     TCG_REG_R5,
                    289:     TCG_REG_R6,
                    290:     TCG_REG_R7,
                    291: #if TCG_TARGET_NB_REGS >= 16
                    292:     TCG_REG_R8,
                    293:     TCG_REG_R9,
                    294:     TCG_REG_R10,
                    295:     TCG_REG_R11,
                    296:     TCG_REG_R12,
                    297:     TCG_REG_R13,
                    298:     TCG_REG_R14,
                    299:     TCG_REG_R15,
                    300: #endif
                    301: };
                    302: 
                    303: #if MAX_OPC_PARAM_IARGS != 4
                    304: # error Fix needed, number of supported input arguments changed!
                    305: #endif
                    306: 
                    307: static const int tcg_target_call_iarg_regs[] = {
                    308:     TCG_REG_R0,
                    309:     TCG_REG_R1,
                    310:     TCG_REG_R2,
                    311:     TCG_REG_R3,
                    312: #if TCG_TARGET_REG_BITS == 32
                    313:     /* 32 bit hosts need 2 * MAX_OPC_PARAM_IARGS registers. */
                    314: #if 0 /* used for TCG_REG_CALL_STACK */
                    315:     TCG_REG_R4,
                    316: #endif
                    317:     TCG_REG_R5,
                    318:     TCG_REG_R6,
                    319:     TCG_REG_R7,
                    320: #if TCG_TARGET_NB_REGS >= 16
                    321:     TCG_REG_R8,
                    322: #else
                    323: # error Too few input registers available
                    324: #endif
                    325: #endif
                    326: };
                    327: 
                    328: static const int tcg_target_call_oarg_regs[] = {
                    329:     TCG_REG_R0,
                    330: #if TCG_TARGET_REG_BITS == 32
                    331:     TCG_REG_R1
                    332: #endif
                    333: };
                    334: 
                    335: #ifndef NDEBUG
                    336: static const char *const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
                    337:     "r00",
                    338:     "r01",
                    339:     "r02",
                    340:     "r03",
                    341:     "r04",
                    342:     "r05",
                    343:     "r06",
                    344:     "r07",
                    345: #if TCG_TARGET_NB_REGS >= 16
                    346:     "r08",
                    347:     "r09",
                    348:     "r10",
                    349:     "r11",
                    350:     "r12",
                    351:     "r13",
                    352:     "r14",
                    353:     "r15",
                    354: #if TCG_TARGET_NB_REGS >= 32
                    355:     "r16",
                    356:     "r17",
                    357:     "r18",
                    358:     "r19",
                    359:     "r20",
                    360:     "r21",
                    361:     "r22",
                    362:     "r23",
                    363:     "r24",
                    364:     "r25",
                    365:     "r26",
                    366:     "r27",
                    367:     "r28",
                    368:     "r29",
                    369:     "r30",
                    370:     "r31"
                    371: #endif
                    372: #endif
                    373: };
                    374: #endif
                    375: 
                    376: static void patch_reloc(uint8_t *code_ptr, int type,
                    377:                         tcg_target_long value, tcg_target_long addend)
                    378: {
                    379:     /* tcg_out_reloc always uses the same type, addend. */
                    380:     assert(type == sizeof(tcg_target_long));
                    381:     assert(addend == 0);
                    382:     assert(value != 0);
                    383:     *(tcg_target_long *)code_ptr = value;
                    384: }
                    385: 
                    386: /* Parse target specific constraints. */
                    387: static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
                    388: {
                    389:     const char *ct_str = *pct_str;
                    390:     switch (ct_str[0]) {
                    391:     case 'r':
                    392:     case 'L':                   /* qemu_ld constraint */
                    393:     case 'S':                   /* qemu_st constraint */
                    394:         ct->ct |= TCG_CT_REG;
                    395:         tcg_regset_set32(ct->u.regs, 0, BIT(TCG_TARGET_NB_REGS) - 1);
                    396:         break;
                    397:     default:
                    398:         return -1;
                    399:     }
                    400:     ct_str++;
                    401:     *pct_str = ct_str;
                    402:     return 0;
                    403: }
                    404: 
                    405: #if defined(CONFIG_DEBUG_TCG_INTERPRETER)
                    406: /* Show current bytecode. Used by tcg interpreter. */
                    407: void tci_disas(uint8_t opc)
                    408: {
                    409:     const TCGOpDef *def = &tcg_op_defs[opc];
                    410:     fprintf(stderr, "TCG %s %u, %u, %u\n",
                    411:             def->name, def->nb_oargs, def->nb_iargs, def->nb_cargs);
                    412: }
                    413: #endif
                    414: 
                    415: /* Write value (native size). */
                    416: static void tcg_out_i(TCGContext *s, tcg_target_ulong v)
                    417: {
                    418:     *(tcg_target_ulong *)s->code_ptr = v;
                    419:     s->code_ptr += sizeof(tcg_target_ulong);
                    420: }
                    421: 
                    422: /* Write 64 bit value. */
                    423: static void tcg_out64(TCGContext *s, uint64_t v)
                    424: {
                    425:     *(uint64_t *)s->code_ptr = v;
                    426:     s->code_ptr += sizeof(v);
                    427: }
                    428: 
                    429: /* Write opcode. */
                    430: static void tcg_out_op_t(TCGContext *s, TCGOpcode op)
                    431: {
                    432:     tcg_out8(s, op);
                    433:     tcg_out8(s, 0);
                    434: }
                    435: 
                    436: /* Write register. */
                    437: static void tcg_out_r(TCGContext *s, TCGArg t0)
                    438: {
                    439:     assert(t0 < TCG_TARGET_NB_REGS);
                    440:     tcg_out8(s, t0);
                    441: }
                    442: 
                    443: /* Write register or constant (native size). */
                    444: static void tcg_out_ri(TCGContext *s, int const_arg, TCGArg arg)
                    445: {
                    446:     if (const_arg) {
                    447:         assert(const_arg == 1);
                    448:         tcg_out8(s, TCG_CONST);
                    449:         tcg_out_i(s, arg);
                    450:     } else {
                    451:         tcg_out_r(s, arg);
                    452:     }
                    453: }
                    454: 
                    455: /* Write register or constant (32 bit). */
                    456: static void tcg_out_ri32(TCGContext *s, int const_arg, TCGArg arg)
                    457: {
                    458:     if (const_arg) {
                    459:         assert(const_arg == 1);
                    460:         tcg_out8(s, TCG_CONST);
                    461:         tcg_out32(s, arg);
                    462:     } else {
                    463:         tcg_out_r(s, arg);
                    464:     }
                    465: }
                    466: 
                    467: #if TCG_TARGET_REG_BITS == 64
                    468: /* Write register or constant (64 bit). */
                    469: static void tcg_out_ri64(TCGContext *s, int const_arg, TCGArg arg)
                    470: {
                    471:     if (const_arg) {
                    472:         assert(const_arg == 1);
                    473:         tcg_out8(s, TCG_CONST);
                    474:         tcg_out64(s, arg);
                    475:     } else {
                    476:         tcg_out_r(s, arg);
                    477:     }
                    478: }
                    479: #endif
                    480: 
                    481: /* Write label. */
                    482: static void tci_out_label(TCGContext *s, TCGArg arg)
                    483: {
                    484:     TCGLabel *label = &s->labels[arg];
                    485:     if (label->has_value) {
                    486:         tcg_out_i(s, label->u.value);
                    487:         assert(label->u.value);
                    488:     } else {
                    489:         tcg_out_reloc(s, s->code_ptr, sizeof(tcg_target_ulong), arg, 0);
                    490:         tcg_out_i(s, 0);
                    491:     }
                    492: }
                    493: 
                    494: static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
                    495:                        tcg_target_long arg2)
                    496: {
                    497:     uint8_t *old_code_ptr = s->code_ptr;
                    498:     if (type == TCG_TYPE_I32) {
                    499:         tcg_out_op_t(s, INDEX_op_ld_i32);
                    500:         tcg_out_r(s, ret);
                    501:         tcg_out_r(s, arg1);
                    502:         tcg_out32(s, arg2);
                    503:     } else {
                    504:         assert(type == TCG_TYPE_I64);
                    505: #if TCG_TARGET_REG_BITS == 64
                    506:         tcg_out_op_t(s, INDEX_op_ld_i64);
                    507:         tcg_out_r(s, ret);
                    508:         tcg_out_r(s, arg1);
                    509:         assert(arg2 == (uint32_t)arg2);
                    510:         tcg_out32(s, arg2);
                    511: #else
                    512:         TODO();
                    513: #endif
                    514:     }
                    515:     old_code_ptr[1] = s->code_ptr - old_code_ptr;
                    516: }
                    517: 
                    518: static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
                    519: {
                    520:     uint8_t *old_code_ptr = s->code_ptr;
                    521:     assert(ret != arg);
                    522: #if TCG_TARGET_REG_BITS == 32
                    523:     tcg_out_op_t(s, INDEX_op_mov_i32);
                    524: #else
                    525:     tcg_out_op_t(s, INDEX_op_mov_i64);
                    526: #endif
                    527:     tcg_out_r(s, ret);
                    528:     tcg_out_r(s, arg);
                    529:     old_code_ptr[1] = s->code_ptr - old_code_ptr;
                    530: }
                    531: 
                    532: static void tcg_out_movi(TCGContext *s, TCGType type,
                    533:                          TCGReg t0, tcg_target_long arg)
                    534: {
                    535:     uint8_t *old_code_ptr = s->code_ptr;
                    536:     uint32_t arg32 = arg;
                    537:     if (type == TCG_TYPE_I32 || arg == arg32) {
                    538:         tcg_out_op_t(s, INDEX_op_movi_i32);
                    539:         tcg_out_r(s, t0);
                    540:         tcg_out32(s, arg32);
                    541:     } else {
                    542:         assert(type == TCG_TYPE_I64);
                    543: #if TCG_TARGET_REG_BITS == 64
                    544:         tcg_out_op_t(s, INDEX_op_movi_i64);
                    545:         tcg_out_r(s, t0);
                    546:         tcg_out64(s, arg);
                    547: #else
                    548:         TODO();
                    549: #endif
                    550:     }
                    551:     old_code_ptr[1] = s->code_ptr - old_code_ptr;
                    552: }
                    553: 
                    554: static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
                    555:                        const int *const_args)
                    556: {
                    557:     uint8_t *old_code_ptr = s->code_ptr;
                    558: 
                    559:     tcg_out_op_t(s, opc);
                    560: 
                    561:     switch (opc) {
                    562:     case INDEX_op_exit_tb:
                    563:         tcg_out64(s, args[0]);
                    564:         break;
                    565:     case INDEX_op_goto_tb:
                    566:         if (s->tb_jmp_offset) {
                    567:             /* Direct jump method. */
                    568:             assert(args[0] < ARRAY_SIZE(s->tb_jmp_offset));
                    569:             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
                    570:             tcg_out32(s, 0);
                    571:         } else {
                    572:             /* Indirect jump method. */
                    573:             TODO();
                    574:         }
                    575:         assert(args[0] < ARRAY_SIZE(s->tb_next_offset));
                    576:         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
                    577:         break;
                    578:     case INDEX_op_br:
                    579:         tci_out_label(s, args[0]);
                    580:         break;
                    581:     case INDEX_op_call:
                    582:         tcg_out_ri(s, const_args[0], args[0]);
                    583:         break;
                    584:     case INDEX_op_jmp:
                    585:         TODO();
                    586:         break;
                    587:     case INDEX_op_setcond_i32:
                    588:         tcg_out_r(s, args[0]);
                    589:         tcg_out_r(s, args[1]);
                    590:         tcg_out_ri32(s, const_args[2], args[2]);
                    591:         tcg_out8(s, args[3]);   /* condition */
                    592:         break;
                    593: #if TCG_TARGET_REG_BITS == 32
                    594:     case INDEX_op_setcond2_i32:
                    595:         /* setcond2_i32 cond, t0, t1_low, t1_high, t2_low, t2_high */
                    596:         tcg_out_r(s, args[0]);
                    597:         tcg_out_r(s, args[1]);
                    598:         tcg_out_r(s, args[2]);
                    599:         tcg_out_ri32(s, const_args[3], args[3]);
                    600:         tcg_out_ri32(s, const_args[4], args[4]);
                    601:         tcg_out8(s, args[5]);   /* condition */
                    602:         break;
                    603: #elif TCG_TARGET_REG_BITS == 64
                    604:     case INDEX_op_setcond_i64:
                    605:         tcg_out_r(s, args[0]);
                    606:         tcg_out_r(s, args[1]);
                    607:         tcg_out_ri64(s, const_args[2], args[2]);
                    608:         tcg_out8(s, args[3]);   /* condition */
                    609:         break;
                    610: #endif
                    611:     case INDEX_op_movi_i32:
                    612:         TODO(); /* Handled by tcg_out_movi? */
                    613:         break;
                    614:     case INDEX_op_ld8u_i32:
                    615:     case INDEX_op_ld8s_i32:
                    616:     case INDEX_op_ld16u_i32:
                    617:     case INDEX_op_ld16s_i32:
                    618:     case INDEX_op_ld_i32:
                    619:     case INDEX_op_st8_i32:
                    620:     case INDEX_op_st16_i32:
                    621:     case INDEX_op_st_i32:
                    622:     case INDEX_op_ld8u_i64:
                    623:     case INDEX_op_ld8s_i64:
                    624:     case INDEX_op_ld16u_i64:
                    625:     case INDEX_op_ld16s_i64:
                    626:     case INDEX_op_ld32u_i64:
                    627:     case INDEX_op_ld32s_i64:
                    628:     case INDEX_op_ld_i64:
                    629:     case INDEX_op_st8_i64:
                    630:     case INDEX_op_st16_i64:
                    631:     case INDEX_op_st32_i64:
                    632:     case INDEX_op_st_i64:
                    633:         tcg_out_r(s, args[0]);
                    634:         tcg_out_r(s, args[1]);
                    635:         assert(args[2] == (uint32_t)args[2]);
                    636:         tcg_out32(s, args[2]);
                    637:         break;
                    638:     case INDEX_op_add_i32:
                    639:     case INDEX_op_sub_i32:
                    640:     case INDEX_op_mul_i32:
                    641:     case INDEX_op_and_i32:
                    642:     case INDEX_op_andc_i32:     /* Optional (TCG_TARGET_HAS_andc_i32). */
                    643:     case INDEX_op_eqv_i32:      /* Optional (TCG_TARGET_HAS_eqv_i32). */
                    644:     case INDEX_op_nand_i32:     /* Optional (TCG_TARGET_HAS_nand_i32). */
                    645:     case INDEX_op_nor_i32:      /* Optional (TCG_TARGET_HAS_nor_i32). */
                    646:     case INDEX_op_or_i32:
                    647:     case INDEX_op_orc_i32:      /* Optional (TCG_TARGET_HAS_orc_i32). */
                    648:     case INDEX_op_xor_i32:
                    649:     case INDEX_op_shl_i32:
                    650:     case INDEX_op_shr_i32:
                    651:     case INDEX_op_sar_i32:
                    652:     case INDEX_op_rotl_i32:     /* Optional (TCG_TARGET_HAS_rot_i32). */
                    653:     case INDEX_op_rotr_i32:     /* Optional (TCG_TARGET_HAS_rot_i32). */
                    654:         tcg_out_r(s, args[0]);
                    655:         tcg_out_ri32(s, const_args[1], args[1]);
                    656:         tcg_out_ri32(s, const_args[2], args[2]);
                    657:         break;
                    658: 
                    659: #if TCG_TARGET_REG_BITS == 64
                    660:     case INDEX_op_mov_i64:
                    661:     case INDEX_op_movi_i64:
                    662:         TODO();
                    663:         break;
                    664:     case INDEX_op_add_i64:
                    665:     case INDEX_op_sub_i64:
                    666:     case INDEX_op_mul_i64:
                    667:     case INDEX_op_and_i64:
                    668:     case INDEX_op_andc_i64:     /* Optional (TCG_TARGET_HAS_andc_i64). */
                    669:     case INDEX_op_eqv_i64:      /* Optional (TCG_TARGET_HAS_eqv_i64). */
                    670:     case INDEX_op_nand_i64:     /* Optional (TCG_TARGET_HAS_nand_i64). */
                    671:     case INDEX_op_nor_i64:      /* Optional (TCG_TARGET_HAS_nor_i64). */
                    672:     case INDEX_op_or_i64:
                    673:     case INDEX_op_orc_i64:      /* Optional (TCG_TARGET_HAS_orc_i64). */
                    674:     case INDEX_op_xor_i64:
                    675:     case INDEX_op_shl_i64:
                    676:     case INDEX_op_shr_i64:
                    677:     case INDEX_op_sar_i64:
                    678:         /* TODO: Implementation of rotl_i64, rotr_i64 missing in tci.c. */
                    679:     case INDEX_op_rotl_i64:     /* Optional (TCG_TARGET_HAS_rot_i64). */
                    680:     case INDEX_op_rotr_i64:     /* Optional (TCG_TARGET_HAS_rot_i64). */
                    681:         tcg_out_r(s, args[0]);
                    682:         tcg_out_ri64(s, const_args[1], args[1]);
                    683:         tcg_out_ri64(s, const_args[2], args[2]);
                    684:         break;
                    685:     case INDEX_op_div_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */
                    686:     case INDEX_op_divu_i64:     /* Optional (TCG_TARGET_HAS_div_i64). */
                    687:     case INDEX_op_rem_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */
                    688:     case INDEX_op_remu_i64:     /* Optional (TCG_TARGET_HAS_div_i64). */
                    689:         TODO();
                    690:         break;
                    691:     case INDEX_op_div2_i64:     /* Optional (TCG_TARGET_HAS_div2_i64). */
                    692:     case INDEX_op_divu2_i64:    /* Optional (TCG_TARGET_HAS_div2_i64). */
                    693:         TODO();
                    694:         break;
                    695:     case INDEX_op_brcond_i64:
                    696:         tcg_out_r(s, args[0]);
                    697:         tcg_out_ri64(s, const_args[1], args[1]);
                    698:         tcg_out8(s, args[2]);           /* condition */
                    699:         tci_out_label(s, args[3]);
                    700:         break;
                    701:     case INDEX_op_bswap16_i64:  /* Optional (TCG_TARGET_HAS_bswap16_i64). */
                    702:     case INDEX_op_bswap32_i64:  /* Optional (TCG_TARGET_HAS_bswap32_i64). */
                    703:     case INDEX_op_bswap64_i64:  /* Optional (TCG_TARGET_HAS_bswap64_i64). */
                    704:     case INDEX_op_not_i64:      /* Optional (TCG_TARGET_HAS_not_i64). */
                    705:     case INDEX_op_neg_i64:      /* Optional (TCG_TARGET_HAS_neg_i64). */
                    706:     case INDEX_op_ext8s_i64:    /* Optional (TCG_TARGET_HAS_ext8s_i64). */
                    707:     case INDEX_op_ext8u_i64:    /* Optional (TCG_TARGET_HAS_ext8u_i64). */
                    708:     case INDEX_op_ext16s_i64:   /* Optional (TCG_TARGET_HAS_ext16s_i64). */
                    709:     case INDEX_op_ext16u_i64:   /* Optional (TCG_TARGET_HAS_ext16u_i64). */
                    710:     case INDEX_op_ext32s_i64:   /* Optional (TCG_TARGET_HAS_ext32s_i64). */
                    711:     case INDEX_op_ext32u_i64:   /* Optional (TCG_TARGET_HAS_ext32u_i64). */
                    712: #endif /* TCG_TARGET_REG_BITS == 64 */
                    713:     case INDEX_op_neg_i32:      /* Optional (TCG_TARGET_HAS_neg_i32). */
                    714:     case INDEX_op_not_i32:      /* Optional (TCG_TARGET_HAS_not_i32). */
                    715:     case INDEX_op_ext8s_i32:    /* Optional (TCG_TARGET_HAS_ext8s_i32). */
                    716:     case INDEX_op_ext16s_i32:   /* Optional (TCG_TARGET_HAS_ext16s_i32). */
                    717:     case INDEX_op_ext8u_i32:    /* Optional (TCG_TARGET_HAS_ext8u_i32). */
                    718:     case INDEX_op_ext16u_i32:   /* Optional (TCG_TARGET_HAS_ext16u_i32). */
                    719:     case INDEX_op_bswap16_i32:  /* Optional (TCG_TARGET_HAS_bswap16_i32). */
                    720:     case INDEX_op_bswap32_i32:  /* Optional (TCG_TARGET_HAS_bswap32_i32). */
                    721:         tcg_out_r(s, args[0]);
                    722:         tcg_out_r(s, args[1]);
                    723:         break;
                    724:     case INDEX_op_div_i32:      /* Optional (TCG_TARGET_HAS_div_i32). */
                    725:     case INDEX_op_divu_i32:     /* Optional (TCG_TARGET_HAS_div_i32). */
                    726:     case INDEX_op_rem_i32:      /* Optional (TCG_TARGET_HAS_div_i32). */
                    727:     case INDEX_op_remu_i32:     /* Optional (TCG_TARGET_HAS_div_i32). */
                    728:         tcg_out_r(s, args[0]);
                    729:         tcg_out_ri32(s, const_args[1], args[1]);
                    730:         tcg_out_ri32(s, const_args[2], args[2]);
                    731:         break;
                    732:     case INDEX_op_div2_i32:     /* Optional (TCG_TARGET_HAS_div2_i32). */
                    733:     case INDEX_op_divu2_i32:    /* Optional (TCG_TARGET_HAS_div2_i32). */
                    734:         TODO();
                    735:         break;
                    736: #if TCG_TARGET_REG_BITS == 32
                    737:     case INDEX_op_add2_i32:
                    738:     case INDEX_op_sub2_i32:
                    739:         tcg_out_r(s, args[0]);
                    740:         tcg_out_r(s, args[1]);
                    741:         tcg_out_r(s, args[2]);
                    742:         tcg_out_r(s, args[3]);
                    743:         tcg_out_r(s, args[4]);
                    744:         tcg_out_r(s, args[5]);
                    745:         break;
                    746:     case INDEX_op_brcond2_i32:
                    747:         tcg_out_r(s, args[0]);
                    748:         tcg_out_r(s, args[1]);
                    749:         tcg_out_ri32(s, const_args[2], args[2]);
                    750:         tcg_out_ri32(s, const_args[3], args[3]);
                    751:         tcg_out8(s, args[4]);           /* condition */
                    752:         tci_out_label(s, args[5]);
                    753:         break;
                    754:     case INDEX_op_mulu2_i32:
                    755:         tcg_out_r(s, args[0]);
                    756:         tcg_out_r(s, args[1]);
                    757:         tcg_out_r(s, args[2]);
                    758:         tcg_out_r(s, args[3]);
                    759:         break;
                    760: #endif
                    761:     case INDEX_op_brcond_i32:
                    762:         tcg_out_r(s, args[0]);
                    763:         tcg_out_ri32(s, const_args[1], args[1]);
                    764:         tcg_out8(s, args[2]);           /* condition */
                    765:         tci_out_label(s, args[3]);
                    766:         break;
                    767:     case INDEX_op_qemu_ld8u:
                    768:     case INDEX_op_qemu_ld8s:
                    769:     case INDEX_op_qemu_ld16u:
                    770:     case INDEX_op_qemu_ld16s:
                    771:     case INDEX_op_qemu_ld32:
                    772: #if TCG_TARGET_REG_BITS == 64
                    773:     case INDEX_op_qemu_ld32s:
                    774:     case INDEX_op_qemu_ld32u:
                    775: #endif
                    776:         tcg_out_r(s, *args++);
                    777:         tcg_out_r(s, *args++);
                    778: #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
                    779:         tcg_out_r(s, *args++);
                    780: #endif
                    781: #ifdef CONFIG_SOFTMMU
                    782:         tcg_out_i(s, *args);
                    783: #endif
                    784:         break;
                    785:     case INDEX_op_qemu_ld64:
                    786:         tcg_out_r(s, *args++);
                    787: #if TCG_TARGET_REG_BITS == 32
                    788:         tcg_out_r(s, *args++);
                    789: #endif
                    790:         tcg_out_r(s, *args++);
                    791: #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
                    792:         tcg_out_r(s, *args++);
                    793: #endif
                    794: #ifdef CONFIG_SOFTMMU
                    795:         tcg_out_i(s, *args);
                    796: #endif
                    797:         break;
                    798:     case INDEX_op_qemu_st8:
                    799:     case INDEX_op_qemu_st16:
                    800:     case INDEX_op_qemu_st32:
1.1.1.2 ! root      801: #ifdef CONFIG_TCG_PASS_AREG0
        !           802:         tcg_out_r(s, TCG_AREG0);
        !           803: #endif
1.1       root      804:         tcg_out_r(s, *args++);
                    805:         tcg_out_r(s, *args++);
                    806: #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
                    807:         tcg_out_r(s, *args++);
                    808: #endif
                    809: #ifdef CONFIG_SOFTMMU
                    810:         tcg_out_i(s, *args);
                    811: #endif
                    812:         break;
                    813:     case INDEX_op_qemu_st64:
1.1.1.2 ! root      814: #ifdef CONFIG_TCG_PASS_AREG0
        !           815:         tcg_out_r(s, TCG_AREG0);
        !           816: #endif
1.1       root      817:         tcg_out_r(s, *args++);
                    818: #if TCG_TARGET_REG_BITS == 32
                    819:         tcg_out_r(s, *args++);
                    820: #endif
                    821:         tcg_out_r(s, *args++);
                    822: #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
                    823:         tcg_out_r(s, *args++);
                    824: #endif
                    825: #ifdef CONFIG_SOFTMMU
                    826:         tcg_out_i(s, *args);
                    827: #endif
                    828:         break;
                    829:     case INDEX_op_end:
                    830:         TODO();
                    831:         break;
                    832:     default:
                    833:         fprintf(stderr, "Missing: %s\n", tcg_op_defs[opc].name);
                    834:         tcg_abort();
                    835:     }
                    836:     old_code_ptr[1] = s->code_ptr - old_code_ptr;
                    837: }
                    838: 
                    839: static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
                    840:                        tcg_target_long arg2)
                    841: {
                    842:     uint8_t *old_code_ptr = s->code_ptr;
                    843:     if (type == TCG_TYPE_I32) {
                    844:         tcg_out_op_t(s, INDEX_op_st_i32);
                    845:         tcg_out_r(s, arg);
                    846:         tcg_out_r(s, arg1);
                    847:         tcg_out32(s, arg2);
                    848:     } else {
                    849:         assert(type == TCG_TYPE_I64);
                    850: #if TCG_TARGET_REG_BITS == 64
                    851:         tcg_out_op_t(s, INDEX_op_st_i64);
                    852:         tcg_out_r(s, arg);
                    853:         tcg_out_r(s, arg1);
                    854:         tcg_out32(s, arg2);
                    855: #else
                    856:         TODO();
                    857: #endif
                    858:     }
                    859:     old_code_ptr[1] = s->code_ptr - old_code_ptr;
                    860: }
                    861: 
                    862: /* Test if a constant matches the constraint. */
                    863: static int tcg_target_const_match(tcg_target_long val,
                    864:                                   const TCGArgConstraint *arg_ct)
                    865: {
                    866:     /* No need to return 0 or 1, 0 or != 0 is good enough. */
                    867:     return arg_ct->ct & TCG_CT_CONST;
                    868: }
                    869: 
                    870: /* Maximum number of register used for input function arguments. */
                    871: static int tcg_target_get_call_iarg_regs_count(int flags)
                    872: {
                    873:     return ARRAY_SIZE(tcg_target_call_iarg_regs);
                    874: }
                    875: 
                    876: static void tcg_target_init(TCGContext *s)
                    877: {
                    878: #if defined(CONFIG_DEBUG_TCG_INTERPRETER)
                    879:     const char *envval = getenv("DEBUG_TCG");
                    880:     if (envval) {
                    881:         loglevel = strtol(envval, NULL, 0);
                    882:     }
                    883: #endif
                    884: 
                    885:     /* The current code uses uint8_t for tcg operations. */
                    886:     assert(ARRAY_SIZE(tcg_op_defs) <= UINT8_MAX);
                    887: 
                    888:     /* Registers available for 32 bit operations. */
                    889:     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0,
                    890:                      BIT(TCG_TARGET_NB_REGS) - 1);
                    891:     /* Registers available for 64 bit operations. */
                    892:     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0,
                    893:                      BIT(TCG_TARGET_NB_REGS) - 1);
                    894:     /* TODO: Which registers should be set here? */
                    895:     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
                    896:                      BIT(TCG_TARGET_NB_REGS) - 1);
                    897:     tcg_regset_clear(s->reserved_regs);
                    898:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
                    899:     tcg_add_target_add_op_defs(tcg_target_op_defs);
1.1.1.2 ! root      900:     tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
1.1       root      901:                   CPU_TEMP_BUF_NLONGS * sizeof(long));
                    902: }
                    903: 
                    904: /* Generate global QEMU prologue and epilogue code. */
                    905: static void tcg_target_qemu_prologue(TCGContext *s)
                    906: {
                    907:     tb_ret_addr = s->code_ptr;
                    908: }

unix.superglobalmegacorp.com

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