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

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] = {
                     27:     "%r0",
                     28:     "%r1",
                     29:     "%rp",
                     30:     "%r3",
                     31:     "%r4",
                     32:     "%r5",
                     33:     "%r6",
                     34:     "%r7",
                     35:     "%r8",
                     36:     "%r9",
                     37:     "%r10",
                     38:     "%r11",
                     39:     "%r12",
                     40:     "%r13",
                     41:     "%r14",
                     42:     "%r15",
                     43:     "%r16",
                     44:     "%r17",
                     45:     "%r18",
                     46:     "%r19",
                     47:     "%r20",
                     48:     "%r21",
                     49:     "%r22",
                     50:     "%r23",
                     51:     "%r24",
                     52:     "%r25",
                     53:     "%r26",
                     54:     "%dp",
                     55:     "%ret0",
                     56:     "%ret1",
                     57:     "%sp",
                     58:     "%r31",
                     59: };
                     60: #endif
                     61: 
                     62: static const int tcg_target_reg_alloc_order[] = {
                     63:     TCG_REG_R4,
                     64:     TCG_REG_R5,
                     65:     TCG_REG_R6,
                     66:     TCG_REG_R7,
                     67:     TCG_REG_R8,
                     68:     TCG_REG_R9,
                     69:     TCG_REG_R10,
                     70:     TCG_REG_R11,
                     71:     TCG_REG_R12,
                     72:     TCG_REG_R13,
                     73: 
                     74:     TCG_REG_R17,
                     75:     TCG_REG_R14,
                     76:     TCG_REG_R15,
                     77:     TCG_REG_R16,
                     78: };
                     79: 
                     80: static const int tcg_target_call_iarg_regs[4] = {
                     81:     TCG_REG_R26,
                     82:     TCG_REG_R25,
                     83:     TCG_REG_R24,
                     84:     TCG_REG_R23,
                     85: };
                     86: 
                     87: static const int tcg_target_call_oarg_regs[2] = {
                     88:     TCG_REG_RET0,
                     89:     TCG_REG_RET1,
                     90: };
                     91: 
                     92: static void patch_reloc(uint8_t *code_ptr, int type,
                     93:                         tcg_target_long value, tcg_target_long addend)
                     94: {
                     95:     switch (type) {
                     96:     case R_PARISC_PCREL17F:
                     97:         hppa_patch17f((uint32_t *)code_ptr, value, addend);
                     98:         break;
                     99:     default:
                    100:         tcg_abort();
                    101:     }
                    102: }
                    103: 
                    104: /* maximum number of register used for input function arguments */
                    105: static inline int tcg_target_get_call_iarg_regs_count(int flags)
                    106: {
                    107:     return 4;
                    108: }
                    109: 
                    110: /* parse target specific constraints */
                    111: static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
                    112: {
                    113:     const char *ct_str;
                    114: 
                    115:     ct_str = *pct_str;
                    116:     switch (ct_str[0]) {
                    117:     case 'r':
                    118:         ct->ct |= TCG_CT_REG;
                    119:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    120:         break;
                    121:     case 'L': /* qemu_ld/st constraint */
                    122:         ct->ct |= TCG_CT_REG;
                    123:         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
                    124:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R26);
                    125:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R25);
                    126:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R24);
                    127:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R23);
                    128:         break;
                    129:     default:
                    130:         return -1;
                    131:     }
                    132:     ct_str++;
                    133:     *pct_str = ct_str;
                    134:     return 0;
                    135: }
                    136: 
                    137: /* test if a constant matches the constraint */
                    138: static inline int tcg_target_const_match(tcg_target_long val,
                    139:                                          const TCGArgConstraint *arg_ct)
                    140: {
                    141:     int ct;
                    142: 
                    143:     ct = arg_ct->ct;
                    144: 
                    145:     /* TODO */
                    146: 
                    147:     return 0;
                    148: }
                    149: 
                    150: #define INSN_OP(x)       ((x) << 26)
                    151: #define INSN_EXT3BR(x)   ((x) << 13)
                    152: #define INSN_EXT3SH(x)   ((x) << 10)
                    153: #define INSN_EXT4(x)     ((x) << 6)
                    154: #define INSN_EXT5(x)     (x)
                    155: #define INSN_EXT6(x)     ((x) << 6)
                    156: #define INSN_EXT7(x)     ((x) << 6)
                    157: #define INSN_EXT8A(x)    ((x) << 6)
                    158: #define INSN_EXT8B(x)    ((x) << 5)
                    159: #define INSN_T(x)        (x)
                    160: #define INSN_R1(x)       ((x) << 16)
                    161: #define INSN_R2(x)       ((x) << 21)
                    162: #define INSN_DEP_LEN(x)  (32 - (x))
                    163: #define INSN_SHDEP_CP(x) ((31 - (x)) << 5)
                    164: #define INSN_SHDEP_P(x)  ((x) << 5)
                    165: #define INSN_COND(x)     ((x) << 13)
                    166: 
                    167: #define COND_NEVER 0
                    168: #define COND_EQUAL 1
                    169: #define COND_LT    2
                    170: #define COND_LTEQ  3
                    171: #define COND_LTU   4
                    172: #define COND_LTUEQ 5
                    173: #define COND_SV    6
                    174: #define COND_OD    7
                    175: 
                    176: 
                    177: /* Logical ADD */
                    178: #define ARITH_ADD  (INSN_OP(0x02) | INSN_EXT6(0x28))
                    179: #define ARITH_AND  (INSN_OP(0x02) | INSN_EXT6(0x08))
                    180: #define ARITH_OR   (INSN_OP(0x02) | INSN_EXT6(0x09))
                    181: #define ARITH_XOR  (INSN_OP(0x02) | INSN_EXT6(0x0a))
                    182: #define ARITH_SUB  (INSN_OP(0x02) | INSN_EXT6(0x10))
                    183: 
                    184: #define SHD        (INSN_OP(0x34) | INSN_EXT3SH(2))
                    185: #define VSHD       (INSN_OP(0x34) | INSN_EXT3SH(0))
                    186: #define DEP        (INSN_OP(0x35) | INSN_EXT3SH(3))
                    187: #define ZDEP       (INSN_OP(0x35) | INSN_EXT3SH(2))
                    188: #define ZVDEP      (INSN_OP(0x35) | INSN_EXT3SH(0))
                    189: #define EXTRU      (INSN_OP(0x34) | INSN_EXT3SH(6))
                    190: #define EXTRS      (INSN_OP(0x34) | INSN_EXT3SH(7))
                    191: #define VEXTRS     (INSN_OP(0x34) | INSN_EXT3SH(5))
                    192: 
                    193: #define SUBI       (INSN_OP(0x25))
                    194: #define MTCTL      (INSN_OP(0x00) | INSN_EXT8B(0xc2))
                    195: 
                    196: #define BL         (INSN_OP(0x3a) | INSN_EXT3BR(0))
                    197: #define BLE_SR4    (INSN_OP(0x39) | (1 << 13))
                    198: #define BV         (INSN_OP(0x3a) | INSN_EXT3BR(6))
                    199: #define BV_N       (INSN_OP(0x3a) | INSN_EXT3BR(6) | 2)
                    200: #define LDIL       (INSN_OP(0x08))
                    201: #define LDO        (INSN_OP(0x0d))
                    202: 
                    203: #define LDB        (INSN_OP(0x10))
                    204: #define LDH        (INSN_OP(0x11))
                    205: #define LDW        (INSN_OP(0x12))
                    206: #define LDWM       (INSN_OP(0x13))
                    207: 
                    208: #define STB        (INSN_OP(0x18))
                    209: #define STH        (INSN_OP(0x19))
                    210: #define STW        (INSN_OP(0x1a))
                    211: #define STWM       (INSN_OP(0x1b))
                    212: 
                    213: #define COMBT      (INSN_OP(0x20))
                    214: #define COMBF      (INSN_OP(0x22))
                    215: 
                    216: static int lowsignext(uint32_t val, int start, int length)
                    217: {
                    218:     return (((val << 1) & ~(~0 << length)) |
                    219:             ((val >> (length - 1)) & 1)) << start;
                    220: }
                    221: 
                    222: static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
                    223: {
                    224:     /* PA1.1 defines COPY as OR r,0,t */
                    225:     tcg_out32(s, ARITH_OR | INSN_T(ret) | INSN_R1(arg) | INSN_R2(TCG_REG_R0));
                    226: 
                    227:     /* PA2.0 defines COPY as LDO 0(r),t
                    228:      * but hppa-dis.c is unaware of this definition */
                    229:     /* tcg_out32(s, LDO | INSN_R1(ret) | INSN_R2(arg) | reassemble_14(0)); */
                    230: }
                    231: 
                    232: static inline void tcg_out_movi(TCGContext *s, TCGType type,
                    233:                                 int ret, tcg_target_long arg)
                    234: {
                    235:     if (arg == (arg & 0x1fff)) {
                    236:         tcg_out32(s, LDO | INSN_R1(ret) | INSN_R2(TCG_REG_R0) |
                    237:                      reassemble_14(arg));
                    238:     } else {
                    239:         tcg_out32(s, LDIL | INSN_R2(ret) |
                    240:                      reassemble_21(lrsel((uint32_t)arg, 0)));
                    241:         if (arg & 0x7ff)
                    242:             tcg_out32(s, LDO | INSN_R1(ret) | INSN_R2(ret) |
                    243:                          reassemble_14(rrsel((uint32_t)arg, 0)));
                    244:     }
                    245: }
                    246: 
                    247: static inline void tcg_out_ld_raw(TCGContext *s, int ret,
                    248:                                   tcg_target_long arg)
                    249: {
                    250:     tcg_out32(s, LDIL | INSN_R2(ret) |
                    251:                  reassemble_21(lrsel((uint32_t)arg, 0)));
                    252:     tcg_out32(s, LDW | INSN_R1(ret) | INSN_R2(ret) |
                    253:                  reassemble_14(rrsel((uint32_t)arg, 0)));
                    254: }
                    255: 
                    256: static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
                    257:                                   tcg_target_long arg)
                    258: {
                    259:     tcg_out_ld_raw(s, ret, arg);
                    260: }
                    261: 
                    262: static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset,
                    263:                                 int op)
                    264: {
                    265:     if (offset == (offset & 0xfff))
                    266:         tcg_out32(s, op | INSN_R1(ret) | INSN_R2(addr) |
                    267:                  reassemble_14(offset));
                    268:     else {
                    269:         fprintf(stderr, "unimplemented %s with offset %d\n", __func__, offset);
                    270:         tcg_abort();
                    271:     }
                    272: }
                    273: 
                    274: static inline void tcg_out_ld(TCGContext *s, TCGType type, int ret,
                    275:                               int arg1, tcg_target_long arg2)
                    276: {
                    277:     fprintf(stderr, "unimplemented %s\n", __func__);
                    278:     tcg_abort();
                    279: }
                    280: 
                    281: static inline void tcg_out_st(TCGContext *s, TCGType type, int ret,
                    282:                               int arg1, tcg_target_long arg2)
                    283: {
                    284:     fprintf(stderr, "unimplemented %s\n", __func__);
                    285:     tcg_abort();
                    286: }
                    287: 
                    288: static inline void tcg_out_arith(TCGContext *s, int t, int r1, int r2, int op)
                    289: {
                    290:     tcg_out32(s, op | INSN_T(t) | INSN_R1(r1) | INSN_R2(r2));
                    291: }
                    292: 
                    293: static inline void tcg_out_arithi(TCGContext *s, int t, int r1,
                    294:                                   tcg_target_long val, int op)
                    295: {
                    296:     tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R20, val);
                    297:     tcg_out_arith(s, t, r1, TCG_REG_R20, op);
                    298: }
                    299: 
                    300: static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
                    301: {
                    302:     tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
                    303: }
                    304: 
                    305: static inline void tcg_out_nop(TCGContext *s)
                    306: {
                    307:     tcg_out32(s, ARITH_OR | INSN_T(TCG_REG_R0) | INSN_R1(TCG_REG_R0) |
                    308:                  INSN_R2(TCG_REG_R0));
                    309: }
                    310: 
                    311: static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg) {
                    312:     tcg_out32(s, EXTRS | INSN_R1(ret) | INSN_R2(arg) |
                    313:                  INSN_SHDEP_P(31) | INSN_DEP_LEN(8));
                    314: }
                    315: 
                    316: static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg) {
                    317:     tcg_out32(s, EXTRS | INSN_R1(ret) | INSN_R2(arg) |
                    318:                  INSN_SHDEP_P(31) | INSN_DEP_LEN(16));
                    319: }
                    320: 
                    321: static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg) {
                    322:     if(ret != arg)
                    323:         tcg_out_mov(s, ret, arg);
                    324:     tcg_out32(s, DEP | INSN_R2(ret) | INSN_R1(ret) |
                    325:                  INSN_SHDEP_CP(15) | INSN_DEP_LEN(8));
                    326:     tcg_out32(s, SHD | INSN_T(ret) | INSN_R1(TCG_REG_R0) |
                    327:                  INSN_R2(ret) | INSN_SHDEP_CP(8));
                    328: }
                    329: 
                    330: static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg, int temp) {
                    331:     tcg_out32(s, SHD | INSN_T(temp) | INSN_R1(arg) |
                    332:                  INSN_R2(arg) | INSN_SHDEP_CP(16));
                    333:     tcg_out32(s, DEP | INSN_R2(temp) | INSN_R1(temp) |
                    334:                  INSN_SHDEP_CP(15) | INSN_DEP_LEN(8));
                    335:     tcg_out32(s, SHD | INSN_T(ret) | INSN_R1(arg) |
                    336:                  INSN_R2(temp) | INSN_SHDEP_CP(8));
                    337: }
                    338: 
                    339: static inline void tcg_out_call(TCGContext *s, void *func)
                    340: {
                    341:     uint32_t val = (uint32_t)__canonicalize_funcptr_for_compare(func);
                    342:     tcg_out32(s, LDIL | INSN_R2(TCG_REG_R20) |
                    343:                  reassemble_21(lrsel(val, 0)));
                    344:     tcg_out32(s, BLE_SR4 | INSN_R2(TCG_REG_R20) |
                    345:                  reassemble_17(rrsel(val, 0) >> 2));
                    346:     tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
                    347: }
                    348: 
                    349: #if defined(CONFIG_SOFTMMU)
                    350: 
                    351: #include "../../softmmu_defs.h"
                    352: 
                    353: static void *qemu_ld_helpers[4] = {
                    354:     __ldb_mmu,
                    355:     __ldw_mmu,
                    356:     __ldl_mmu,
                    357:     __ldq_mmu,
                    358: };
                    359: 
                    360: static void *qemu_st_helpers[4] = {
                    361:     __stb_mmu,
                    362:     __stw_mmu,
                    363:     __stl_mmu,
                    364:     __stq_mmu,
                    365: };
                    366: #endif
                    367: 
                    368: static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
                    369: {
                    370:     int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
                    371: #if defined(CONFIG_SOFTMMU)
                    372:     uint32_t *label1_ptr, *label2_ptr;
                    373: #endif
                    374: #if TARGET_LONG_BITS == 64
                    375: #if defined(CONFIG_SOFTMMU)
                    376:     uint32_t *label3_ptr;
                    377: #endif
                    378:     int addr_reg2;
                    379: #endif
                    380: 
                    381:     data_reg = *args++;
                    382:     if (opc == 3)
                    383:         data_reg2 = *args++;
                    384:     else
1.1.1.2 ! root      385:         data_reg2 = 0; /* suppress warning */
1.1       root      386:     addr_reg = *args++;
                    387: #if TARGET_LONG_BITS == 64
                    388:     addr_reg2 = *args++;
                    389: #endif
                    390:     mem_index = *args;
                    391:     s_bits = opc & 3;
                    392: 
                    393:     r0 = TCG_REG_R26;
                    394:     r1 = TCG_REG_R25;
                    395: 
                    396: #if defined(CONFIG_SOFTMMU)
                    397:     tcg_out_mov(s, r1, addr_reg);
                    398: 
                    399:     tcg_out_mov(s, r0, addr_reg);
                    400: 
                    401:     tcg_out32(s, SHD | INSN_T(r1) | INSN_R1(TCG_REG_R0) | INSN_R2(r1) |
                    402:                  INSN_SHDEP_CP(TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS));
                    403: 
                    404:     tcg_out_arithi(s, r0, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
                    405:                    ARITH_AND);
                    406: 
                    407:     tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
                    408:                    ARITH_AND);
                    409: 
                    410:     tcg_out_arith(s, r1, r1, TCG_AREG0, ARITH_ADD);
                    411:     tcg_out_arithi(s, r1, r1,
                    412:                    offsetof(CPUState, tlb_table[mem_index][0].addr_read),
                    413:                    ARITH_ADD);
                    414: 
                    415:     tcg_out_ldst(s, TCG_REG_R20, r1, 0, LDW);
                    416: 
                    417: #if TARGET_LONG_BITS == 32
                    418:     /* if equal, jump to label1 */
                    419:     label1_ptr = (uint32_t *)s->code_ptr;
                    420:     tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
                    421:                  INSN_COND(COND_EQUAL));
                    422:     tcg_out_mov(s, r0, addr_reg); /* delay slot */
                    423: #else
                    424:     /* if not equal, jump to label3 */
                    425:     label3_ptr = (uint32_t *)s->code_ptr;
                    426:     tcg_out32(s, COMBF | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
                    427:                  INSN_COND(COND_EQUAL));
                    428:     tcg_out_mov(s, r0, addr_reg); /* delay slot */
                    429: 
                    430:     tcg_out_ldst(s, TCG_REG_R20, r1, 4, LDW);
                    431: 
                    432:     /* if equal, jump to label1 */
                    433:     label1_ptr = (uint32_t *)s->code_ptr;
                    434:     tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(addr_reg2) |
                    435:                  INSN_COND(COND_EQUAL));
                    436:     tcg_out_nop(s); /* delay slot */
                    437: 
                    438:     /* label3: */
                    439:     *label3_ptr |= reassemble_12((uint32_t *)s->code_ptr - label3_ptr - 2);
                    440: #endif
                    441: 
                    442: #if TARGET_LONG_BITS == 32
                    443:     tcg_out_mov(s, TCG_REG_R26, addr_reg);
                    444:     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R25, mem_index);
                    445: #else
                    446:     tcg_out_mov(s, TCG_REG_R26, addr_reg);
                    447:     tcg_out_mov(s, TCG_REG_R25, addr_reg2);
                    448:     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R24, mem_index);
                    449: #endif
                    450: 
                    451:     tcg_out_call(s, qemu_ld_helpers[s_bits]);
                    452: 
                    453:     switch(opc) {
                    454:         case 0 | 4:
                    455:             tcg_out_ext8s(s, data_reg, TCG_REG_RET0);
                    456:             break;
                    457:         case 1 | 4:
                    458:             tcg_out_ext16s(s, data_reg, TCG_REG_RET0);
                    459:             break;
                    460:         case 0:
                    461:         case 1:
                    462:         case 2:
                    463:         default:
                    464:             tcg_out_mov(s, data_reg, TCG_REG_RET0);
                    465:             break;
                    466:         case 3:
                    467:             tcg_abort();
                    468:             tcg_out_mov(s, data_reg, TCG_REG_RET0);
                    469:             tcg_out_mov(s, data_reg2, TCG_REG_RET1);
                    470:             break;
                    471:     }
                    472: 
                    473:     /* jump to label2 */
                    474:     label2_ptr = (uint32_t *)s->code_ptr;
                    475:     tcg_out32(s, BL | INSN_R2(TCG_REG_R0) | 2);
                    476: 
                    477:     /* label1: */
                    478:     *label1_ptr |= reassemble_12((uint32_t *)s->code_ptr - label1_ptr - 2);
                    479: 
                    480:     tcg_out_arithi(s, TCG_REG_R20, r1,
                    481:                    offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_read),
                    482:                    ARITH_ADD);
                    483:     tcg_out_ldst(s, TCG_REG_R20, TCG_REG_R20, 0, LDW);
                    484:     tcg_out_arith(s, r0, r0, TCG_REG_R20, ARITH_ADD);
                    485: #else
                    486:     r0 = addr_reg;
                    487: #endif
                    488: 
                    489: #ifdef TARGET_WORDS_BIGENDIAN
                    490:     bswap = 0;
                    491: #else
                    492:     bswap = 1;
                    493: #endif
                    494:     switch (opc) {
                    495:         case 0:
                    496:             tcg_out_ldst(s, data_reg, r0, 0, LDB);
                    497:             break;
                    498:         case 0 | 4:
                    499:             tcg_out_ldst(s, data_reg, r0, 0, LDB);
                    500:             tcg_out_ext8s(s, data_reg, data_reg);
                    501:             break;
                    502:         case 1:
                    503:             tcg_out_ldst(s, data_reg, r0, 0, LDH);
                    504:             if (bswap)
                    505:                 tcg_out_bswap16(s, data_reg, data_reg);
                    506:             break;
                    507:         case 1 | 4:
                    508:             tcg_out_ldst(s, data_reg, r0, 0, LDH);
                    509:             if (bswap)
                    510:                 tcg_out_bswap16(s, data_reg, data_reg);
                    511:             tcg_out_ext16s(s, data_reg, data_reg);
                    512:             break;
                    513:         case 2:
                    514:             tcg_out_ldst(s, data_reg, r0, 0, LDW);
                    515:             if (bswap)
                    516:                 tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
                    517:             break;
                    518:         case 3:
                    519:             tcg_abort();
                    520:             if (!bswap) {
                    521:                 tcg_out_ldst(s, data_reg, r0, 0, LDW);
                    522:                 tcg_out_ldst(s, data_reg2, r0, 4, LDW);
                    523:             } else {
                    524:                 tcg_out_ldst(s, data_reg, r0, 4, LDW);
                    525:                 tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
                    526:                 tcg_out_ldst(s, data_reg2, r0, 0, LDW);
                    527:                 tcg_out_bswap32(s, data_reg2, data_reg2, TCG_REG_R20);
                    528:             }
                    529:             break;
                    530:         default:
                    531:             tcg_abort();
                    532:     }
                    533: 
                    534: #if defined(CONFIG_SOFTMMU)
                    535:     /* label2: */
                    536:     *label2_ptr |= reassemble_17((uint32_t *)s->code_ptr - label2_ptr - 2);
                    537: #endif
                    538: }
                    539: 
                    540: static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
                    541: {
                    542:     int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
                    543: #if defined(CONFIG_SOFTMMU)
                    544:     uint32_t *label1_ptr, *label2_ptr;
                    545: #endif
                    546: #if TARGET_LONG_BITS == 64
                    547: #if defined(CONFIG_SOFTMMU)
                    548:     uint32_t *label3_ptr;
                    549: #endif
                    550:     int addr_reg2;
                    551: #endif
                    552: 
                    553:     data_reg = *args++;
                    554:     if (opc == 3)
                    555:         data_reg2 = *args++;
                    556:     else
1.1.1.2 ! root      557:         data_reg2 = 0; /* suppress warning */
1.1       root      558:     addr_reg = *args++;
                    559: #if TARGET_LONG_BITS == 64
                    560:     addr_reg2 = *args++;
                    561: #endif
                    562:     mem_index = *args;
                    563: 
                    564:     s_bits = opc;
                    565: 
                    566:     r0 = TCG_REG_R26;
                    567:     r1 = TCG_REG_R25;
                    568: 
                    569: #if defined(CONFIG_SOFTMMU)
                    570:     tcg_out_mov(s, r1, addr_reg);
                    571: 
                    572:     tcg_out_mov(s, r0, addr_reg);
                    573: 
                    574:     tcg_out32(s, SHD | INSN_T(r1) | INSN_R1(TCG_REG_R0) | INSN_R2(r1) |
                    575:                  INSN_SHDEP_CP(TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS));
                    576: 
                    577:     tcg_out_arithi(s, r0, r0, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
                    578:                    ARITH_AND);
                    579: 
                    580:     tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
                    581:                    ARITH_AND);
                    582: 
                    583:     tcg_out_arith(s, r1, r1, TCG_AREG0, ARITH_ADD);
                    584:     tcg_out_arithi(s, r1, r1,
                    585:                    offsetof(CPUState, tlb_table[mem_index][0].addr_write),
                    586:                    ARITH_ADD);
                    587: 
                    588:     tcg_out_ldst(s, TCG_REG_R20, r1, 0, LDW);
                    589: 
                    590: #if TARGET_LONG_BITS == 32
                    591:     /* if equal, jump to label1 */
                    592:     label1_ptr = (uint32_t *)s->code_ptr;
                    593:     tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
                    594:                  INSN_COND(COND_EQUAL));
                    595:     tcg_out_mov(s, r0, addr_reg); /* delay slot */
                    596: #else
                    597:     /* if not equal, jump to label3 */
                    598:     label3_ptr = (uint32_t *)s->code_ptr;
                    599:     tcg_out32(s, COMBF | INSN_R1(TCG_REG_R20) | INSN_R2(r0) |
                    600:                  INSN_COND(COND_EQUAL));
                    601:     tcg_out_mov(s, r0, addr_reg); /* delay slot */
                    602: 
                    603:     tcg_out_ldst(s, TCG_REG_R20, r1, 4, LDW);
                    604: 
                    605:     /* if equal, jump to label1 */
                    606:     label1_ptr = (uint32_t *)s->code_ptr;
                    607:     tcg_out32(s, COMBT | INSN_R1(TCG_REG_R20) | INSN_R2(addr_reg2) |
                    608:                  INSN_COND(COND_EQUAL));
                    609:     tcg_out_nop(s); /* delay slot */
                    610: 
                    611:     /* label3: */
                    612:     *label3_ptr |= reassemble_12((uint32_t *)s->code_ptr - label3_ptr - 2);
                    613: #endif
                    614: 
                    615:     tcg_out_mov(s, TCG_REG_R26, addr_reg);
                    616: #if TARGET_LONG_BITS == 64
                    617:     tcg_out_mov(s, TCG_REG_R25, addr_reg2);
                    618:     if (opc == 3) {
                    619:         tcg_abort();
                    620:         tcg_out_mov(s, TCG_REG_R24, data_reg);
                    621:         tcg_out_mov(s, TCG_REG_R23, data_reg2);
                    622:         /* TODO: push mem_index */
                    623:         tcg_abort();
                    624:     } else {
                    625:         switch(opc) {
                    626:         case 0:
                    627:             tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R24) | INSN_R2(data_reg) |
                    628:                          INSN_SHDEP_P(31) | INSN_DEP_LEN(8));
                    629:             break;
                    630:         case 1:
                    631:             tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R24) | INSN_R2(data_reg) |
                    632:                          INSN_SHDEP_P(31) | INSN_DEP_LEN(16));
                    633:             break;
                    634:         case 2:
                    635:             tcg_out_mov(s, TCG_REG_R24, data_reg);
                    636:             break;
                    637:         }
                    638:         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R23, mem_index);
                    639:     }
                    640: #else
                    641:     if (opc == 3) {
                    642:         tcg_abort();
                    643:         tcg_out_mov(s, TCG_REG_R25, data_reg);
                    644:         tcg_out_mov(s, TCG_REG_R24, data_reg2);
                    645:         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R23, mem_index);
                    646:     } else {
                    647:         switch(opc) {
                    648:         case 0:
                    649:             tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R25) | INSN_R2(data_reg) |
                    650:                          INSN_SHDEP_P(31) | INSN_DEP_LEN(8));
                    651:             break;
                    652:         case 1:
                    653:             tcg_out32(s, EXTRU | INSN_R1(TCG_REG_R25) | INSN_R2(data_reg) |
                    654:                          INSN_SHDEP_P(31) | INSN_DEP_LEN(16));
                    655:             break;
                    656:         case 2:
                    657:             tcg_out_mov(s, TCG_REG_R25, data_reg);
                    658:             break;
                    659:         }
                    660:         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R24, mem_index);
                    661:     }
                    662: #endif
                    663:     tcg_out_call(s, qemu_st_helpers[s_bits]);
                    664: 
                    665:     /* jump to label2 */
                    666:     label2_ptr = (uint32_t *)s->code_ptr;
                    667:     tcg_out32(s, BL | INSN_R2(TCG_REG_R0) | 2);
                    668: 
                    669:     /* label1: */
                    670:     *label1_ptr |= reassemble_12((uint32_t *)s->code_ptr - label1_ptr - 2);
                    671: 
                    672:     tcg_out_arithi(s, TCG_REG_R20, r1,
                    673:                    offsetof(CPUTLBEntry, addend) - offsetof(CPUTLBEntry, addr_write),
                    674:                    ARITH_ADD);
                    675:     tcg_out_ldst(s, TCG_REG_R20, TCG_REG_R20, 0, LDW);
                    676:     tcg_out_arith(s, r0, r0, TCG_REG_R20, ARITH_ADD);
                    677: #else
                    678:     r0 = addr_reg;
                    679: #endif
                    680: 
                    681: #ifdef TARGET_WORDS_BIGENDIAN
                    682:     bswap = 0;
                    683: #else
                    684:     bswap = 1;
                    685: #endif
                    686:     switch (opc) {
                    687:     case 0:
                    688:         tcg_out_ldst(s, data_reg, r0, 0, STB);
                    689:         break;
                    690:     case 1:
                    691:         if (bswap) {
                    692:             tcg_out_bswap16(s, TCG_REG_R20, data_reg);
                    693:             data_reg = TCG_REG_R20;
                    694:         }
                    695:         tcg_out_ldst(s, data_reg, r0, 0, STH);
                    696:         break;
                    697:     case 2:
                    698:         if (bswap) {
                    699:             tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
                    700:             data_reg = TCG_REG_R20;
                    701:         }
                    702:         tcg_out_ldst(s, data_reg, r0, 0, STW);
                    703:         break;
                    704:     case 3:
                    705:         tcg_abort();
                    706:         if (!bswap) {
                    707:             tcg_out_ldst(s, data_reg, r0, 0, STW);
                    708:             tcg_out_ldst(s, data_reg2, r0, 4, STW);
                    709:         } else {
                    710:             tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
                    711:             tcg_out_ldst(s, TCG_REG_R20, r0, 4, STW);
                    712:             tcg_out_bswap32(s, TCG_REG_R20, data_reg2, TCG_REG_R20);
                    713:             tcg_out_ldst(s, TCG_REG_R20, r0, 0, STW);
                    714:         }
                    715:         break;
                    716:     default:
                    717:         tcg_abort();
                    718:     }
                    719: 
                    720: #if defined(CONFIG_SOFTMMU)
                    721:     /* label2: */
                    722:     *label2_ptr |= reassemble_17((uint32_t *)s->code_ptr - label2_ptr - 2);
                    723: #endif
                    724: }
                    725: 
                    726: static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
                    727:                               const int *const_args)
                    728: {
                    729:     int c;
                    730: 
                    731:     switch (opc) {
                    732:     case INDEX_op_exit_tb:
                    733:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RET0, args[0]);
                    734:         tcg_out32(s, BV_N | INSN_R2(TCG_REG_R18));
                    735:         break;
                    736:     case INDEX_op_goto_tb:
                    737:         if (s->tb_jmp_offset) {
                    738:             /* direct jump method */
                    739:             fprintf(stderr, "goto_tb direct\n");
                    740:             tcg_abort();
                    741:             tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R20, args[0]);
                    742:             tcg_out32(s, BV_N | INSN_R2(TCG_REG_R20));
                    743:             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
                    744:         } else {
                    745:             /* indirect jump method */
                    746:             tcg_out_ld_ptr(s, TCG_REG_R20,
                    747:                            (tcg_target_long)(s->tb_next + args[0]));
                    748:             tcg_out32(s, BV_N | INSN_R2(TCG_REG_R20));
                    749:         }
                    750:         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
                    751:         break;
                    752:     case INDEX_op_call:
                    753:         tcg_out32(s, BLE_SR4 | INSN_R2(args[0]));
                    754:         tcg_out_mov(s, TCG_REG_RP, TCG_REG_R31);
                    755:         break;
                    756:     case INDEX_op_jmp:
                    757:         fprintf(stderr, "unimplemented jmp\n");
                    758:         tcg_abort();
                    759:         break;
                    760:     case INDEX_op_br:
                    761:         fprintf(stderr, "unimplemented br\n");
                    762:         tcg_abort();
                    763:         break;
                    764:     case INDEX_op_movi_i32:
                    765:         tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
                    766:         break;
                    767: 
                    768:     case INDEX_op_ld8u_i32:
                    769:         tcg_out_ldst(s, args[0], args[1], args[2], LDB);
                    770:         break;
                    771:     case INDEX_op_ld8s_i32:
                    772:         tcg_out_ldst(s, args[0], args[1], args[2], LDB);
                    773:         tcg_out_ext8s(s, args[0], args[0]);
                    774:         break;
                    775:     case INDEX_op_ld16u_i32:
                    776:         tcg_out_ldst(s, args[0], args[1], args[2], LDH);
                    777:         break;
                    778:     case INDEX_op_ld16s_i32:
                    779:         tcg_out_ldst(s, args[0], args[1], args[2], LDH);
                    780:         tcg_out_ext16s(s, args[0], args[0]);
                    781:         break;
                    782:     case INDEX_op_ld_i32:
                    783:         tcg_out_ldst(s, args[0], args[1], args[2], LDW);
                    784:         break;
                    785: 
                    786:     case INDEX_op_st8_i32:
                    787:         tcg_out_ldst(s, args[0], args[1], args[2], STB);
                    788:         break;
                    789:     case INDEX_op_st16_i32:
                    790:         tcg_out_ldst(s, args[0], args[1], args[2], STH);
                    791:         break;
                    792:     case INDEX_op_st_i32:
                    793:         tcg_out_ldst(s, args[0], args[1], args[2], STW);
                    794:         break;
                    795: 
                    796:     case INDEX_op_sub_i32:
                    797:         c = ARITH_SUB;
                    798:         goto gen_arith;
                    799:     case INDEX_op_and_i32:
                    800:         c = ARITH_AND;
                    801:         goto gen_arith;
                    802:     case INDEX_op_or_i32:
                    803:         c = ARITH_OR;
                    804:         goto gen_arith;
                    805:     case INDEX_op_xor_i32:
                    806:         c = ARITH_XOR;
                    807:         goto gen_arith;
                    808:     case INDEX_op_add_i32:
                    809:         c = ARITH_ADD;
                    810:         goto gen_arith;
                    811: 
                    812:     case INDEX_op_shl_i32:
                    813:         tcg_out32(s, SUBI | INSN_R1(TCG_REG_R20) | INSN_R2(args[2]) |
                    814:                      lowsignext(0x1f, 0, 11));
                    815:         tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(TCG_REG_R20));
                    816:         tcg_out32(s, ZVDEP | INSN_R2(args[0]) | INSN_R1(args[1]) |
                    817:                      INSN_DEP_LEN(32));
                    818:         break;
                    819:     case INDEX_op_shr_i32:
                    820:         tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(args[2]));
                    821:         tcg_out32(s, VSHD | INSN_T(args[0]) | INSN_R1(TCG_REG_R0) |
                    822:                      INSN_R2(args[1]));
                    823:         break;
                    824:     case INDEX_op_sar_i32:
                    825:         tcg_out32(s, SUBI | INSN_R1(TCG_REG_R20) | INSN_R2(args[2]) |
                    826:                      lowsignext(0x1f, 0, 11));
                    827:         tcg_out32(s, MTCTL | INSN_R2(11) | INSN_R1(TCG_REG_R20));
                    828:         tcg_out32(s, VEXTRS | INSN_R1(args[0]) | INSN_R2(args[1]) |
                    829:                      INSN_DEP_LEN(32));
                    830:         break;
                    831: 
                    832:     case INDEX_op_mul_i32:
                    833:         fprintf(stderr, "unimplemented mul\n");
                    834:         tcg_abort();
                    835:         break;
                    836:     case INDEX_op_mulu2_i32:
                    837:         fprintf(stderr, "unimplemented mulu2\n");
                    838:         tcg_abort();
                    839:         break;
                    840:     case INDEX_op_div2_i32:
                    841:         fprintf(stderr, "unimplemented div2\n");
                    842:         tcg_abort();
                    843:         break;
                    844:     case INDEX_op_divu2_i32:
                    845:         fprintf(stderr, "unimplemented divu2\n");
                    846:         tcg_abort();
                    847:         break;
                    848: 
                    849:     case INDEX_op_brcond_i32:
                    850:         fprintf(stderr, "unimplemented brcond\n");
                    851:         tcg_abort();
                    852:         break;
                    853: 
                    854:     case INDEX_op_qemu_ld8u:
                    855:         tcg_out_qemu_ld(s, args, 0);
                    856:         break;
                    857:     case INDEX_op_qemu_ld8s:
                    858:         tcg_out_qemu_ld(s, args, 0 | 4);
                    859:         break;
                    860:     case INDEX_op_qemu_ld16u:
                    861:         tcg_out_qemu_ld(s, args, 1);
                    862:         break;
                    863:     case INDEX_op_qemu_ld16s:
                    864:         tcg_out_qemu_ld(s, args, 1 | 4);
                    865:         break;
                    866:     case INDEX_op_qemu_ld32u:
                    867:         tcg_out_qemu_ld(s, args, 2);
                    868:         break;
                    869: 
                    870:     case INDEX_op_qemu_st8:
                    871:         tcg_out_qemu_st(s, args, 0);
                    872:         break;
                    873:     case INDEX_op_qemu_st16:
                    874:         tcg_out_qemu_st(s, args, 1);
                    875:         break;
                    876:     case INDEX_op_qemu_st32:
                    877:         tcg_out_qemu_st(s, args, 2);
                    878:         break;
                    879: 
                    880:     default:
                    881:         fprintf(stderr, "unknown opcode 0x%x\n", opc);
                    882:         tcg_abort();
                    883:     }
                    884:     return;
                    885: 
                    886: gen_arith:
                    887:     tcg_out_arith(s, args[0], args[1], args[2], c);
                    888: }
                    889: 
                    890: static const TCGTargetOpDef hppa_op_defs[] = {
                    891:     { INDEX_op_exit_tb, { } },
                    892:     { INDEX_op_goto_tb, { } },
                    893: 
                    894:     { INDEX_op_call, { "r" } },
                    895:     { INDEX_op_jmp, { "r" } },
                    896:     { INDEX_op_br, { } },
                    897: 
                    898:     { INDEX_op_mov_i32, { "r", "r" } },
                    899:     { INDEX_op_movi_i32, { "r" } },
                    900:     { INDEX_op_ld8u_i32, { "r", "r" } },
                    901:     { INDEX_op_ld8s_i32, { "r", "r" } },
                    902:     { INDEX_op_ld16u_i32, { "r", "r" } },
                    903:     { INDEX_op_ld16s_i32, { "r", "r" } },
                    904:     { INDEX_op_ld_i32, { "r", "r" } },
                    905:     { INDEX_op_st8_i32, { "r", "r" } },
                    906:     { INDEX_op_st16_i32, { "r", "r" } },
                    907:     { INDEX_op_st_i32, { "r", "r" } },
                    908: 
                    909:     { INDEX_op_add_i32, { "r", "r", "r" } },
                    910:     { INDEX_op_sub_i32, { "r", "r", "r" } },
                    911:     { INDEX_op_and_i32, { "r", "r", "r" } },
                    912:     { INDEX_op_or_i32, { "r", "r", "r" } },
                    913:     { INDEX_op_xor_i32, { "r", "r", "r" } },
                    914: 
                    915:     { INDEX_op_shl_i32, { "r", "r", "r" } },
                    916:     { INDEX_op_shr_i32, { "r", "r", "r" } },
                    917:     { INDEX_op_sar_i32, { "r", "r", "r" } },
                    918: 
                    919:     { INDEX_op_brcond_i32, { "r", "r" } },
                    920: 
                    921: #if TARGET_LONG_BITS == 32
                    922:     { INDEX_op_qemu_ld8u, { "r", "L" } },
                    923:     { INDEX_op_qemu_ld8s, { "r", "L" } },
                    924:     { INDEX_op_qemu_ld16u, { "r", "L" } },
                    925:     { INDEX_op_qemu_ld16s, { "r", "L" } },
                    926:     { INDEX_op_qemu_ld32u, { "r", "L" } },
                    927:     { INDEX_op_qemu_ld64, { "r", "r", "L" } },
                    928: 
                    929:     { INDEX_op_qemu_st8, { "L", "L" } },
                    930:     { INDEX_op_qemu_st16, { "L", "L" } },
                    931:     { INDEX_op_qemu_st32, { "L", "L" } },
                    932:     { INDEX_op_qemu_st64, { "L", "L", "L" } },
                    933: #else
                    934:     { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
                    935:     { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
                    936:     { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
                    937:     { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
                    938:     { INDEX_op_qemu_ld32u, { "r", "L", "L" } },
                    939:     { INDEX_op_qemu_ld32s, { "r", "L", "L" } },
                    940:     { INDEX_op_qemu_ld64, { "r", "r", "L", "L" } },
                    941: 
                    942:     { INDEX_op_qemu_st8, { "L", "L", "L" } },
                    943:     { INDEX_op_qemu_st16, { "L", "L", "L" } },
                    944:     { INDEX_op_qemu_st32, { "L", "L", "L" } },
                    945:     { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
                    946: #endif
                    947:     { -1 },
                    948: };
                    949: 
                    950: void tcg_target_init(TCGContext *s)
                    951: {
                    952:     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
                    953:     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
                    954:                      (1 << TCG_REG_R20) |
                    955:                      (1 << TCG_REG_R21) |
                    956:                      (1 << TCG_REG_R22) |
                    957:                      (1 << TCG_REG_R23) |
                    958:                      (1 << TCG_REG_R24) |
                    959:                      (1 << TCG_REG_R25) |
                    960:                      (1 << TCG_REG_R26));
                    961: 
                    962:     tcg_regset_clear(s->reserved_regs);
                    963:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);  /* hardwired to zero */
                    964:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R1);  /* addil target */
                    965:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RP);  /* link register */
                    966:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R3);  /* frame pointer */
                    967:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R18); /* return pointer */
                    968:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R19); /* clobbered w/o pic */
                    969:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R20); /* reserved */
                    970:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_DP);  /* data pointer */
                    971:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);  /* stack pointer */
                    972:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */
                    973: 
                    974:     tcg_add_target_add_op_defs(hppa_op_defs);
                    975: }

unix.superglobalmegacorp.com

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