Annotation of qemu/tcg/s390/tcg-target.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  * Tiny Code Generator for QEMU
                      3:  *
                      4:  * Copyright (c) 2009 Ulrich Hecht <[email protected]>
1.1.1.2   root        5:  * Copyright (c) 2009 Alexander Graf <[email protected]>
                      6:  * Copyright (c) 2010 Richard Henderson <[email protected]>
1.1       root        7:  *
                      8:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      9:  * of this software and associated documentation files (the "Software"), to deal
                     10:  * in the Software without restriction, including without limitation the rights
                     11:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     12:  * copies of the Software, and to permit persons to whom the Software is
                     13:  * furnished to do so, subject to the following conditions:
                     14:  *
                     15:  * The above copyright notice and this permission notice shall be included in
                     16:  * all copies or substantial portions of the Software.
                     17:  *
                     18:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     19:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     20:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     21:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     22:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     23:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     24:  * THE SOFTWARE.
                     25:  */
                     26: 
1.1.1.2   root       27: /* ??? The translation blocks produced by TCG are generally small enough to
                     28:    be entirely reachable with a 16-bit displacement.  Leaving the option for
                     29:    a 32-bit displacement here Just In Case.  */
                     30: #define USE_LONG_BRANCHES 0
                     31: 
                     32: #define TCG_CT_CONST_32    0x0100
                     33: #define TCG_CT_CONST_NEG   0x0200
                     34: #define TCG_CT_CONST_ADDI  0x0400
                     35: #define TCG_CT_CONST_MULI  0x0800
                     36: #define TCG_CT_CONST_ANDI  0x1000
                     37: #define TCG_CT_CONST_ORI   0x2000
                     38: #define TCG_CT_CONST_XORI  0x4000
                     39: #define TCG_CT_CONST_CMPI  0x8000
                     40: 
                     41: /* Several places within the instruction set 0 means "no register"
                     42:    rather than TCG_REG_R0.  */
                     43: #define TCG_REG_NONE    0
                     44: 
                     45: /* A scratch register that may be be used throughout the backend.  */
                     46: #define TCG_TMP0        TCG_REG_R14
                     47: 
                     48: #ifdef CONFIG_USE_GUEST_BASE
                     49: #define TCG_GUEST_BASE_REG TCG_REG_R13
                     50: #else
                     51: #define TCG_GUEST_BASE_REG TCG_REG_R0
                     52: #endif
                     53: 
                     54: #ifndef GUEST_BASE
                     55: #define GUEST_BASE 0
                     56: #endif
                     57: 
                     58: 
                     59: /* All of the following instructions are prefixed with their instruction
                     60:    format, and are defined as 8- or 16-bit quantities, even when the two
                     61:    halves of the 16-bit quantity may appear 32 bits apart in the insn.
                     62:    This makes it easy to copy the values from the tables in Appendix B.  */
                     63: typedef enum S390Opcode {
                     64:     RIL_AFI     = 0xc209,
                     65:     RIL_AGFI    = 0xc208,
                     66:     RIL_ALGFI   = 0xc20a,
                     67:     RIL_BRASL   = 0xc005,
                     68:     RIL_BRCL    = 0xc004,
                     69:     RIL_CFI     = 0xc20d,
                     70:     RIL_CGFI    = 0xc20c,
                     71:     RIL_CLFI    = 0xc20f,
                     72:     RIL_CLGFI   = 0xc20e,
                     73:     RIL_IIHF    = 0xc008,
                     74:     RIL_IILF    = 0xc009,
                     75:     RIL_LARL    = 0xc000,
                     76:     RIL_LGFI    = 0xc001,
                     77:     RIL_LGRL    = 0xc408,
                     78:     RIL_LLIHF   = 0xc00e,
                     79:     RIL_LLILF   = 0xc00f,
                     80:     RIL_LRL     = 0xc40d,
                     81:     RIL_MSFI    = 0xc201,
                     82:     RIL_MSGFI   = 0xc200,
                     83:     RIL_NIHF    = 0xc00a,
                     84:     RIL_NILF    = 0xc00b,
                     85:     RIL_OIHF    = 0xc00c,
                     86:     RIL_OILF    = 0xc00d,
                     87:     RIL_XIHF    = 0xc006,
                     88:     RIL_XILF    = 0xc007,
                     89: 
                     90:     RI_AGHI     = 0xa70b,
                     91:     RI_AHI      = 0xa70a,
                     92:     RI_BRC      = 0xa704,
                     93:     RI_IIHH     = 0xa500,
                     94:     RI_IIHL     = 0xa501,
                     95:     RI_IILH     = 0xa502,
                     96:     RI_IILL     = 0xa503,
                     97:     RI_LGHI     = 0xa709,
                     98:     RI_LLIHH    = 0xa50c,
                     99:     RI_LLIHL    = 0xa50d,
                    100:     RI_LLILH    = 0xa50e,
                    101:     RI_LLILL    = 0xa50f,
                    102:     RI_MGHI     = 0xa70d,
                    103:     RI_MHI      = 0xa70c,
                    104:     RI_NIHH     = 0xa504,
                    105:     RI_NIHL     = 0xa505,
                    106:     RI_NILH     = 0xa506,
                    107:     RI_NILL     = 0xa507,
                    108:     RI_OIHH     = 0xa508,
                    109:     RI_OIHL     = 0xa509,
                    110:     RI_OILH     = 0xa50a,
                    111:     RI_OILL     = 0xa50b,
                    112: 
                    113:     RIE_CGIJ    = 0xec7c,
                    114:     RIE_CGRJ    = 0xec64,
                    115:     RIE_CIJ     = 0xec7e,
                    116:     RIE_CLGRJ   = 0xec65,
                    117:     RIE_CLIJ    = 0xec7f,
                    118:     RIE_CLGIJ   = 0xec7d,
                    119:     RIE_CLRJ    = 0xec77,
                    120:     RIE_CRJ     = 0xec76,
                    121: 
                    122:     RRE_AGR     = 0xb908,
                    123:     RRE_CGR     = 0xb920,
                    124:     RRE_CLGR    = 0xb921,
                    125:     RRE_DLGR    = 0xb987,
                    126:     RRE_DLR     = 0xb997,
                    127:     RRE_DSGFR   = 0xb91d,
                    128:     RRE_DSGR    = 0xb90d,
                    129:     RRE_LGBR    = 0xb906,
                    130:     RRE_LCGR    = 0xb903,
                    131:     RRE_LGFR    = 0xb914,
                    132:     RRE_LGHR    = 0xb907,
                    133:     RRE_LGR     = 0xb904,
                    134:     RRE_LLGCR   = 0xb984,
                    135:     RRE_LLGFR   = 0xb916,
                    136:     RRE_LLGHR   = 0xb985,
                    137:     RRE_LRVR    = 0xb91f,
                    138:     RRE_LRVGR   = 0xb90f,
                    139:     RRE_LTGR    = 0xb902,
                    140:     RRE_MSGR    = 0xb90c,
                    141:     RRE_MSR     = 0xb252,
                    142:     RRE_NGR     = 0xb980,
                    143:     RRE_OGR     = 0xb981,
                    144:     RRE_SGR     = 0xb909,
                    145:     RRE_XGR     = 0xb982,
                    146: 
                    147:     RR_AR       = 0x1a,
                    148:     RR_BASR     = 0x0d,
                    149:     RR_BCR      = 0x07,
                    150:     RR_CLR      = 0x15,
                    151:     RR_CR       = 0x19,
                    152:     RR_DR       = 0x1d,
                    153:     RR_LCR      = 0x13,
                    154:     RR_LR       = 0x18,
                    155:     RR_LTR      = 0x12,
                    156:     RR_NR       = 0x14,
                    157:     RR_OR       = 0x16,
                    158:     RR_SR       = 0x1b,
                    159:     RR_XR       = 0x17,
                    160: 
                    161:     RSY_RLL     = 0xeb1d,
                    162:     RSY_RLLG    = 0xeb1c,
                    163:     RSY_SLLG    = 0xeb0d,
                    164:     RSY_SRAG    = 0xeb0a,
                    165:     RSY_SRLG    = 0xeb0c,
                    166: 
                    167:     RS_SLL      = 0x89,
                    168:     RS_SRA      = 0x8a,
                    169:     RS_SRL      = 0x88,
                    170: 
                    171:     RXY_AG      = 0xe308,
                    172:     RXY_AY      = 0xe35a,
                    173:     RXY_CG      = 0xe320,
                    174:     RXY_CY      = 0xe359,
                    175:     RXY_LB      = 0xe376,
                    176:     RXY_LG      = 0xe304,
                    177:     RXY_LGB     = 0xe377,
                    178:     RXY_LGF     = 0xe314,
                    179:     RXY_LGH     = 0xe315,
                    180:     RXY_LHY     = 0xe378,
                    181:     RXY_LLGC    = 0xe390,
                    182:     RXY_LLGF    = 0xe316,
                    183:     RXY_LLGH    = 0xe391,
                    184:     RXY_LMG     = 0xeb04,
                    185:     RXY_LRV     = 0xe31e,
                    186:     RXY_LRVG    = 0xe30f,
                    187:     RXY_LRVH    = 0xe31f,
                    188:     RXY_LY      = 0xe358,
                    189:     RXY_STCY    = 0xe372,
                    190:     RXY_STG     = 0xe324,
                    191:     RXY_STHY    = 0xe370,
                    192:     RXY_STMG    = 0xeb24,
                    193:     RXY_STRV    = 0xe33e,
                    194:     RXY_STRVG   = 0xe32f,
                    195:     RXY_STRVH   = 0xe33f,
                    196:     RXY_STY     = 0xe350,
                    197: 
                    198:     RX_A        = 0x5a,
                    199:     RX_C        = 0x59,
                    200:     RX_L        = 0x58,
                    201:     RX_LH       = 0x48,
                    202:     RX_ST       = 0x50,
                    203:     RX_STC      = 0x42,
                    204:     RX_STH      = 0x40,
                    205: } S390Opcode;
                    206: 
                    207: #define LD_SIGNED      0x04
                    208: #define LD_UINT8       0x00
                    209: #define LD_INT8        (LD_UINT8 | LD_SIGNED)
                    210: #define LD_UINT16      0x01
                    211: #define LD_INT16       (LD_UINT16 | LD_SIGNED)
                    212: #define LD_UINT32      0x02
                    213: #define LD_INT32       (LD_UINT32 | LD_SIGNED)
                    214: #define LD_UINT64      0x03
                    215: #define LD_INT64       (LD_UINT64 | LD_SIGNED)
                    216: 
                    217: #ifndef NDEBUG
                    218: static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
                    219:     "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
                    220:     "%r8", "%r9", "%r10" "%r11" "%r12" "%r13" "%r14" "%r15"
                    221: };
                    222: #endif
                    223: 
                    224: /* Since R6 is a potential argument register, choose it last of the
                    225:    call-saved registers.  Likewise prefer the call-clobbered registers
                    226:    in reverse order to maximize the chance of avoiding the arguments.  */
1.1       root      227: static const int tcg_target_reg_alloc_order[] = {
1.1.1.2   root      228:     TCG_REG_R13,
                    229:     TCG_REG_R12,
                    230:     TCG_REG_R11,
                    231:     TCG_REG_R10,
                    232:     TCG_REG_R9,
                    233:     TCG_REG_R8,
                    234:     TCG_REG_R7,
                    235:     TCG_REG_R6,
                    236:     TCG_REG_R14,
                    237:     TCG_REG_R0,
                    238:     TCG_REG_R1,
                    239:     TCG_REG_R5,
                    240:     TCG_REG_R4,
                    241:     TCG_REG_R3,
                    242:     TCG_REG_R2,
1.1       root      243: };
                    244: 
                    245: static const int tcg_target_call_iarg_regs[] = {
1.1.1.2   root      246:     TCG_REG_R2,
                    247:     TCG_REG_R3,
                    248:     TCG_REG_R4,
                    249:     TCG_REG_R5,
                    250:     TCG_REG_R6,
1.1       root      251: };
                    252: 
                    253: static const int tcg_target_call_oarg_regs[] = {
1.1.1.2   root      254:     TCG_REG_R2,
1.1.1.4 ! root      255: #if TCG_TARGET_REG_BITS == 32
        !           256:     TCG_REG_R3
        !           257: #endif
1.1.1.2   root      258: };
                    259: 
                    260: #define S390_CC_EQ      8
                    261: #define S390_CC_LT      4
                    262: #define S390_CC_GT      2
                    263: #define S390_CC_OV      1
                    264: #define S390_CC_NE      (S390_CC_LT | S390_CC_GT)
                    265: #define S390_CC_LE      (S390_CC_LT | S390_CC_EQ)
                    266: #define S390_CC_GE      (S390_CC_GT | S390_CC_EQ)
                    267: #define S390_CC_NEVER   0
                    268: #define S390_CC_ALWAYS  15
                    269: 
                    270: /* Condition codes that result from a COMPARE and COMPARE LOGICAL.  */
                    271: static const uint8_t tcg_cond_to_s390_cond[10] = {
                    272:     [TCG_COND_EQ]  = S390_CC_EQ,
                    273:     [TCG_COND_NE]  = S390_CC_NE,
                    274:     [TCG_COND_LT]  = S390_CC_LT,
                    275:     [TCG_COND_LE]  = S390_CC_LE,
                    276:     [TCG_COND_GT]  = S390_CC_GT,
                    277:     [TCG_COND_GE]  = S390_CC_GE,
                    278:     [TCG_COND_LTU] = S390_CC_LT,
                    279:     [TCG_COND_LEU] = S390_CC_LE,
                    280:     [TCG_COND_GTU] = S390_CC_GT,
                    281:     [TCG_COND_GEU] = S390_CC_GE,
                    282: };
                    283: 
                    284: /* Condition codes that result from a LOAD AND TEST.  Here, we have no
                    285:    unsigned instruction variation, however since the test is vs zero we
                    286:    can re-map the outcomes appropriately.  */
                    287: static const uint8_t tcg_cond_to_ltr_cond[10] = {
                    288:     [TCG_COND_EQ]  = S390_CC_EQ,
                    289:     [TCG_COND_NE]  = S390_CC_NE,
                    290:     [TCG_COND_LT]  = S390_CC_LT,
                    291:     [TCG_COND_LE]  = S390_CC_LE,
                    292:     [TCG_COND_GT]  = S390_CC_GT,
                    293:     [TCG_COND_GE]  = S390_CC_GE,
                    294:     [TCG_COND_LTU] = S390_CC_NEVER,
                    295:     [TCG_COND_LEU] = S390_CC_EQ,
                    296:     [TCG_COND_GTU] = S390_CC_NE,
                    297:     [TCG_COND_GEU] = S390_CC_ALWAYS,
                    298: };
                    299: 
                    300: #ifdef CONFIG_SOFTMMU
                    301: 
                    302: #include "../../softmmu_defs.h"
                    303: 
                    304: static void *qemu_ld_helpers[4] = {
                    305:     __ldb_mmu,
                    306:     __ldw_mmu,
                    307:     __ldl_mmu,
                    308:     __ldq_mmu,
                    309: };
                    310: 
                    311: static void *qemu_st_helpers[4] = {
                    312:     __stb_mmu,
                    313:     __stw_mmu,
                    314:     __stl_mmu,
                    315:     __stq_mmu,
1.1       root      316: };
1.1.1.2   root      317: #endif
                    318: 
                    319: static uint8_t *tb_ret_addr;
                    320: 
                    321: /* A list of relevant facilities used by this translator.  Some of these
                    322:    are required for proper operation, and these are checked at startup.  */
                    323: 
                    324: #define FACILITY_ZARCH_ACTIVE  (1ULL << (63 - 2))
                    325: #define FACILITY_LONG_DISP     (1ULL << (63 - 18))
                    326: #define FACILITY_EXT_IMM       (1ULL << (63 - 21))
                    327: #define FACILITY_GEN_INST_EXT  (1ULL << (63 - 34))
                    328: 
                    329: static uint64_t facilities;
1.1       root      330: 
                    331: static void patch_reloc(uint8_t *code_ptr, int type,
1.1.1.2   root      332:                         tcg_target_long value, tcg_target_long addend)
1.1       root      333: {
1.1.1.2   root      334:     tcg_target_long code_ptr_tl = (tcg_target_long)code_ptr;
                    335:     tcg_target_long pcrel2;
                    336: 
                    337:     /* ??? Not the usual definition of "addend".  */
                    338:     pcrel2 = (value - (code_ptr_tl + addend)) >> 1;
                    339: 
                    340:     switch (type) {
                    341:     case R_390_PC16DBL:
                    342:         assert(pcrel2 == (int16_t)pcrel2);
                    343:         *(int16_t *)code_ptr = pcrel2;
                    344:         break;
                    345:     case R_390_PC32DBL:
                    346:         assert(pcrel2 == (int32_t)pcrel2);
                    347:         *(int32_t *)code_ptr = pcrel2;
                    348:         break;
                    349:     default:
                    350:         tcg_abort();
                    351:         break;
                    352:     }
1.1       root      353: }
                    354: 
1.1.1.2   root      355: static int tcg_target_get_call_iarg_regs_count(int flags)
1.1       root      356: {
1.1.1.2   root      357:     return sizeof(tcg_target_call_iarg_regs) / sizeof(int);
1.1       root      358: }
                    359: 
                    360: /* parse target specific constraints */
                    361: static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
                    362: {
1.1.1.2   root      363:     const char *ct_str = *pct_str;
                    364: 
                    365:     switch (ct_str[0]) {
                    366:     case 'r':                  /* all registers */
                    367:         ct->ct |= TCG_CT_REG;
                    368:         tcg_regset_set32(ct->u.regs, 0, 0xffff);
                    369:         break;
                    370:     case 'R':                  /* not R0 */
                    371:         ct->ct |= TCG_CT_REG;
                    372:         tcg_regset_set32(ct->u.regs, 0, 0xffff);
                    373:         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
                    374:         break;
                    375:     case 'L':                  /* qemu_ld/st constraint */
                    376:         ct->ct |= TCG_CT_REG;
                    377:         tcg_regset_set32(ct->u.regs, 0, 0xffff);
                    378:         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R2);
                    379:         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
                    380:         break;
                    381:     case 'a':                  /* force R2 for division */
                    382:         ct->ct |= TCG_CT_REG;
                    383:         tcg_regset_clear(ct->u.regs);
                    384:         tcg_regset_set_reg(ct->u.regs, TCG_REG_R2);
                    385:         break;
                    386:     case 'b':                  /* force R3 for division */
                    387:         ct->ct |= TCG_CT_REG;
                    388:         tcg_regset_clear(ct->u.regs);
                    389:         tcg_regset_set_reg(ct->u.regs, TCG_REG_R3);
                    390:         break;
                    391:     case 'N':                  /* force immediate negate */
                    392:         ct->ct |= TCG_CT_CONST_NEG;
                    393:         break;
                    394:     case 'W':                  /* force 32-bit ("word") immediate */
                    395:         ct->ct |= TCG_CT_CONST_32;
                    396:         break;
                    397:     case 'I':
                    398:         ct->ct |= TCG_CT_CONST_ADDI;
                    399:         break;
                    400:     case 'K':
                    401:         ct->ct |= TCG_CT_CONST_MULI;
                    402:         break;
                    403:     case 'A':
                    404:         ct->ct |= TCG_CT_CONST_ANDI;
                    405:         break;
                    406:     case 'O':
                    407:         ct->ct |= TCG_CT_CONST_ORI;
                    408:         break;
                    409:     case 'X':
                    410:         ct->ct |= TCG_CT_CONST_XORI;
                    411:         break;
                    412:     case 'C':
                    413:         ct->ct |= TCG_CT_CONST_CMPI;
                    414:         break;
                    415:     default:
                    416:         return -1;
                    417:     }
                    418:     ct_str++;
                    419:     *pct_str = ct_str;
                    420: 
1.1       root      421:     return 0;
                    422: }
                    423: 
1.1.1.2   root      424: /* Immediates to be used with logical AND.  This is an optimization only,
                    425:    since a full 64-bit immediate AND can always be performed with 4 sequential
                    426:    NI[LH][LH] instructions.  What we're looking for is immediates that we
                    427:    can load efficiently, and the immediate load plus the reg-reg AND is
                    428:    smaller than the sequential NI's.  */
                    429: 
                    430: static int tcg_match_andi(int ct, tcg_target_ulong val)
                    431: {
                    432:     int i;
                    433: 
                    434:     if (facilities & FACILITY_EXT_IMM) {
                    435:         if (ct & TCG_CT_CONST_32) {
                    436:             /* All 32-bit ANDs can be performed with 1 48-bit insn.  */
                    437:             return 1;
                    438:         }
                    439: 
                    440:         /* Zero-extensions.  */
                    441:         if (val == 0xff || val == 0xffff || val == 0xffffffff) {
                    442:             return 1;
                    443:         }
                    444:     } else {
                    445:         if (ct & TCG_CT_CONST_32) {
                    446:             val = (uint32_t)val;
                    447:         } else if (val == 0xffffffff) {
                    448:             return 1;
                    449:         }
                    450:     }
                    451: 
                    452:     /* Try all 32-bit insns that can perform it in one go.  */
                    453:     for (i = 0; i < 4; i++) {
                    454:         tcg_target_ulong mask = ~(0xffffull << i*16);
                    455:         if ((val & mask) == mask) {
                    456:             return 1;
                    457:         }
                    458:     }
                    459: 
                    460:     /* Look for 16-bit values performing the mask.  These are better
                    461:        to load with LLI[LH][LH].  */
                    462:     for (i = 0; i < 4; i++) {
                    463:         tcg_target_ulong mask = 0xffffull << i*16;
                    464:         if ((val & mask) == val) {
                    465:             return 0;
                    466:         }
                    467:     }
                    468: 
                    469:     /* Look for 32-bit values performing the 64-bit mask.  These
                    470:        are better to load with LLI[LH]F, or if extended immediates
                    471:        not available, with a pair of LLI insns.  */
                    472:     if ((ct & TCG_CT_CONST_32) == 0) {
                    473:         if (val <= 0xffffffff || (val & 0xffffffff) == 0) {
                    474:             return 0;
                    475:         }
                    476:     }
                    477: 
                    478:     return 1;
                    479: }
                    480: 
                    481: /* Immediates to be used with logical OR.  This is an optimization only,
                    482:    since a full 64-bit immediate OR can always be performed with 4 sequential
                    483:    OI[LH][LH] instructions.  What we're looking for is immediates that we
                    484:    can load efficiently, and the immediate load plus the reg-reg OR is
                    485:    smaller than the sequential OI's.  */
                    486: 
                    487: static int tcg_match_ori(int ct, tcg_target_long val)
                    488: {
                    489:     if (facilities & FACILITY_EXT_IMM) {
                    490:         if (ct & TCG_CT_CONST_32) {
                    491:             /* All 32-bit ORs can be performed with 1 48-bit insn.  */
                    492:             return 1;
                    493:         }
                    494:     }
                    495: 
                    496:     /* Look for negative values.  These are best to load with LGHI.  */
                    497:     if (val < 0) {
                    498:         if (val == (int16_t)val) {
                    499:             return 0;
                    500:         }
                    501:         if (facilities & FACILITY_EXT_IMM) {
                    502:             if (val == (int32_t)val) {
                    503:                 return 0;
                    504:             }
                    505:         }
                    506:     }
                    507: 
                    508:     return 1;
                    509: }
                    510: 
                    511: /* Immediates to be used with logical XOR.  This is almost, but not quite,
                    512:    only an optimization.  XOR with immediate is only supported with the
                    513:    extended-immediate facility.  That said, there are a few patterns for
                    514:    which it is better to load the value into a register first.  */
                    515: 
                    516: static int tcg_match_xori(int ct, tcg_target_long val)
                    517: {
                    518:     if ((facilities & FACILITY_EXT_IMM) == 0) {
                    519:         return 0;
                    520:     }
                    521: 
                    522:     if (ct & TCG_CT_CONST_32) {
                    523:         /* All 32-bit XORs can be performed with 1 48-bit insn.  */
                    524:         return 1;
                    525:     }
                    526: 
                    527:     /* Look for negative values.  These are best to load with LGHI.  */
                    528:     if (val < 0 && val == (int32_t)val) {
                    529:         return 0;
                    530:     }
                    531: 
                    532:     return 1;
                    533: }
                    534: 
                    535: /* Imediates to be used with comparisons.  */
                    536: 
                    537: static int tcg_match_cmpi(int ct, tcg_target_long val)
                    538: {
                    539:     if (facilities & FACILITY_EXT_IMM) {
                    540:         /* The COMPARE IMMEDIATE instruction is available.  */
                    541:         if (ct & TCG_CT_CONST_32) {
                    542:             /* We have a 32-bit immediate and can compare against anything.  */
                    543:             return 1;
                    544:         } else {
                    545:             /* ??? We have no insight here into whether the comparison is
                    546:                signed or unsigned.  The COMPARE IMMEDIATE insn uses a 32-bit
                    547:                signed immediate, and the COMPARE LOGICAL IMMEDIATE insn uses
                    548:                a 32-bit unsigned immediate.  If we were to use the (semi)
                    549:                obvious "val == (int32_t)val" we would be enabling unsigned
                    550:                comparisons vs very large numbers.  The only solution is to
                    551:                take the intersection of the ranges.  */
                    552:             /* ??? Another possible solution is to simply lie and allow all
                    553:                constants here and force the out-of-range values into a temp
                    554:                register in tgen_cmp when we have knowledge of the actual
                    555:                comparison code in use.  */
                    556:             return val >= 0 && val <= 0x7fffffff;
                    557:         }
                    558:     } else {
                    559:         /* Only the LOAD AND TEST instruction is available.  */
                    560:         return val == 0;
                    561:     }
                    562: }
                    563: 
1.1       root      564: /* Test if a constant matches the constraint. */
1.1.1.2   root      565: static int tcg_target_const_match(tcg_target_long val,
                    566:                                   const TCGArgConstraint *arg_ct)
1.1       root      567: {
1.1.1.2   root      568:     int ct = arg_ct->ct;
                    569: 
                    570:     if (ct & TCG_CT_CONST) {
                    571:         return 1;
                    572:     }
                    573: 
                    574:     /* Handle the modifiers.  */
                    575:     if (ct & TCG_CT_CONST_NEG) {
                    576:         val = -val;
                    577:     }
                    578:     if (ct & TCG_CT_CONST_32) {
                    579:         val = (int32_t)val;
                    580:     }
                    581: 
                    582:     /* The following are mutually exclusive.  */
                    583:     if (ct & TCG_CT_CONST_ADDI) {
                    584:         /* Immediates that may be used with add.  If we have the
                    585:            extended-immediates facility then we have ADD IMMEDIATE
                    586:            with signed and unsigned 32-bit, otherwise we have only
                    587:            ADD HALFWORD IMMEDIATE with a signed 16-bit.  */
                    588:         if (facilities & FACILITY_EXT_IMM) {
                    589:             return val == (int32_t)val || val == (uint32_t)val;
                    590:         } else {
                    591:             return val == (int16_t)val;
                    592:         }
                    593:     } else if (ct & TCG_CT_CONST_MULI) {
                    594:         /* Immediates that may be used with multiply.  If we have the
                    595:            general-instruction-extensions, then we have MULTIPLY SINGLE
                    596:            IMMEDIATE with a signed 32-bit, otherwise we have only
                    597:            MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit.  */
                    598:         if (facilities & FACILITY_GEN_INST_EXT) {
                    599:             return val == (int32_t)val;
                    600:         } else {
                    601:             return val == (int16_t)val;
                    602:         }
                    603:     } else if (ct & TCG_CT_CONST_ANDI) {
                    604:         return tcg_match_andi(ct, val);
                    605:     } else if (ct & TCG_CT_CONST_ORI) {
                    606:         return tcg_match_ori(ct, val);
                    607:     } else if (ct & TCG_CT_CONST_XORI) {
                    608:         return tcg_match_xori(ct, val);
                    609:     } else if (ct & TCG_CT_CONST_CMPI) {
                    610:         return tcg_match_cmpi(ct, val);
                    611:     }
                    612: 
1.1       root      613:     return 0;
                    614: }
                    615: 
1.1.1.2   root      616: /* Emit instructions according to the given instruction format.  */
                    617: 
                    618: static void tcg_out_insn_RR(TCGContext *s, S390Opcode op, TCGReg r1, TCGReg r2)
                    619: {
                    620:     tcg_out16(s, (op << 8) | (r1 << 4) | r2);
                    621: }
                    622: 
                    623: static void tcg_out_insn_RRE(TCGContext *s, S390Opcode op,
                    624:                              TCGReg r1, TCGReg r2)
                    625: {
                    626:     tcg_out32(s, (op << 16) | (r1 << 4) | r2);
                    627: }
                    628: 
                    629: static void tcg_out_insn_RI(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
                    630: {
                    631:     tcg_out32(s, (op << 16) | (r1 << 20) | (i2 & 0xffff));
                    632: }
                    633: 
                    634: static void tcg_out_insn_RIL(TCGContext *s, S390Opcode op, TCGReg r1, int i2)
                    635: {
                    636:     tcg_out16(s, op | (r1 << 4));
                    637:     tcg_out32(s, i2);
                    638: }
                    639: 
                    640: static void tcg_out_insn_RS(TCGContext *s, S390Opcode op, TCGReg r1,
                    641:                             TCGReg b2, TCGReg r3, int disp)
                    642: {
                    643:     tcg_out32(s, (op << 24) | (r1 << 20) | (r3 << 16) | (b2 << 12)
                    644:               | (disp & 0xfff));
                    645: }
                    646: 
                    647: static void tcg_out_insn_RSY(TCGContext *s, S390Opcode op, TCGReg r1,
                    648:                              TCGReg b2, TCGReg r3, int disp)
                    649: {
                    650:     tcg_out16(s, (op & 0xff00) | (r1 << 4) | r3);
                    651:     tcg_out32(s, (op & 0xff) | (b2 << 28)
                    652:               | ((disp & 0xfff) << 16) | ((disp & 0xff000) >> 4));
                    653: }
                    654: 
                    655: #define tcg_out_insn_RX   tcg_out_insn_RS
                    656: #define tcg_out_insn_RXY  tcg_out_insn_RSY
                    657: 
                    658: /* Emit an opcode with "type-checking" of the format.  */
                    659: #define tcg_out_insn(S, FMT, OP, ...) \
                    660:     glue(tcg_out_insn_,FMT)(S, glue(glue(FMT,_),OP), ## __VA_ARGS__)
                    661: 
                    662: 
                    663: /* emit 64-bit shifts */
                    664: static void tcg_out_sh64(TCGContext* s, S390Opcode op, TCGReg dest,
                    665:                          TCGReg src, TCGReg sh_reg, int sh_imm)
                    666: {
                    667:     tcg_out_insn_RSY(s, op, dest, sh_reg, src, sh_imm);
                    668: }
                    669: 
                    670: /* emit 32-bit shifts */
                    671: static void tcg_out_sh32(TCGContext* s, S390Opcode op, TCGReg dest,
                    672:                          TCGReg sh_reg, int sh_imm)
                    673: {
                    674:     tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
                    675: }
                    676: 
                    677: static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg dst, TCGReg src)
                    678: {
                    679:     if (src != dst) {
                    680:         if (type == TCG_TYPE_I32) {
                    681:             tcg_out_insn(s, RR, LR, dst, src);
                    682:         } else {
                    683:             tcg_out_insn(s, RRE, LGR, dst, src);
                    684:         }
                    685:     }
                    686: }
                    687: 
1.1       root      688: /* load a register with an immediate value */
1.1.1.2   root      689: static void tcg_out_movi(TCGContext *s, TCGType type,
                    690:                          TCGReg ret, tcg_target_long sval)
1.1       root      691: {
1.1.1.2   root      692:     static const S390Opcode lli_insns[4] = {
                    693:         RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH
                    694:     };
                    695: 
                    696:     tcg_target_ulong uval = sval;
                    697:     int i;
                    698: 
                    699:     if (type == TCG_TYPE_I32) {
                    700:         uval = (uint32_t)sval;
                    701:         sval = (int32_t)sval;
                    702:     }
                    703: 
                    704:     /* Try all 32-bit insns that can load it in one go.  */
                    705:     if (sval >= -0x8000 && sval < 0x8000) {
                    706:         tcg_out_insn(s, RI, LGHI, ret, sval);
                    707:         return;
                    708:     }
                    709: 
                    710:     for (i = 0; i < 4; i++) {
                    711:         tcg_target_long mask = 0xffffull << i*16;
                    712:         if ((uval & mask) == uval) {
                    713:             tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16);
                    714:             return;
                    715:         }
                    716:     }
                    717: 
                    718:     /* Try all 48-bit insns that can load it in one go.  */
                    719:     if (facilities & FACILITY_EXT_IMM) {
                    720:         if (sval == (int32_t)sval) {
                    721:             tcg_out_insn(s, RIL, LGFI, ret, sval);
                    722:             return;
                    723:         }
                    724:         if (uval <= 0xffffffff) {
                    725:             tcg_out_insn(s, RIL, LLILF, ret, uval);
                    726:             return;
                    727:         }
                    728:         if ((uval & 0xffffffff) == 0) {
                    729:             tcg_out_insn(s, RIL, LLIHF, ret, uval >> 31 >> 1);
                    730:             return;
                    731:         }
                    732:     }
                    733: 
                    734:     /* Try for PC-relative address load.  */
                    735:     if ((sval & 1) == 0) {
                    736:         intptr_t off = (sval - (intptr_t)s->code_ptr) >> 1;
                    737:         if (off == (int32_t)off) {
                    738:             tcg_out_insn(s, RIL, LARL, ret, off);
                    739:             return;
                    740:         }
                    741:     }
                    742: 
                    743:     /* If extended immediates are not present, then we may have to issue
                    744:        several instructions to load the low 32 bits.  */
                    745:     if (!(facilities & FACILITY_EXT_IMM)) {
                    746:         /* A 32-bit unsigned value can be loaded in 2 insns.  And given
                    747:            that the lli_insns loop above did not succeed, we know that
                    748:            both insns are required.  */
                    749:         if (uval <= 0xffffffff) {
                    750:             tcg_out_insn(s, RI, LLILL, ret, uval);
                    751:             tcg_out_insn(s, RI, IILH, ret, uval >> 16);
                    752:             return;
                    753:         }
                    754: 
                    755:         /* If all high bits are set, the value can be loaded in 2 or 3 insns.
                    756:            We first want to make sure that all the high bits get set.  With
                    757:            luck the low 16-bits can be considered negative to perform that for
                    758:            free, otherwise we load an explicit -1.  */
                    759:         if (sval >> 31 >> 1 == -1) {
                    760:             if (uval & 0x8000) {
                    761:                 tcg_out_insn(s, RI, LGHI, ret, uval);
                    762:             } else {
                    763:                 tcg_out_insn(s, RI, LGHI, ret, -1);
                    764:                 tcg_out_insn(s, RI, IILL, ret, uval);
                    765:             }
                    766:             tcg_out_insn(s, RI, IILH, ret, uval >> 16);
                    767:             return;
                    768:         }
                    769:     }
                    770: 
                    771:     /* If we get here, both the high and low parts have non-zero bits.  */
                    772: 
                    773:     /* Recurse to load the lower 32-bits.  */
                    774:     tcg_out_movi(s, TCG_TYPE_I32, ret, sval);
                    775: 
                    776:     /* Insert data into the high 32-bits.  */
                    777:     uval = uval >> 31 >> 1;
                    778:     if (facilities & FACILITY_EXT_IMM) {
                    779:         if (uval < 0x10000) {
                    780:             tcg_out_insn(s, RI, IIHL, ret, uval);
                    781:         } else if ((uval & 0xffff) == 0) {
                    782:             tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
                    783:         } else {
                    784:             tcg_out_insn(s, RIL, IIHF, ret, uval);
                    785:         }
                    786:     } else {
                    787:         if (uval & 0xffff) {
                    788:             tcg_out_insn(s, RI, IIHL, ret, uval);
                    789:         }
                    790:         if (uval & 0xffff0000) {
                    791:             tcg_out_insn(s, RI, IIHH, ret, uval >> 16);
                    792:         }
                    793:     }
                    794: }
                    795: 
                    796: 
                    797: /* Emit a load/store type instruction.  Inputs are:
                    798:    DATA:     The register to be loaded or stored.
                    799:    BASE+OFS: The effective address.
                    800:    OPC_RX:   If the operation has an RX format opcode (e.g. STC), otherwise 0.
                    801:    OPC_RXY:  The RXY format opcode for the operation (e.g. STCY).  */
                    802: 
                    803: static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
                    804:                         TCGReg data, TCGReg base, TCGReg index,
                    805:                         tcg_target_long ofs)
                    806: {
                    807:     if (ofs < -0x80000 || ofs >= 0x80000) {
                    808:         /* Combine the low 16 bits of the offset with the actual load insn;
                    809:            the high 48 bits must come from an immediate load.  */
                    810:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, ofs & ~0xffff);
                    811:         ofs &= 0xffff;
                    812: 
                    813:         /* If we were already given an index register, add it in.  */
                    814:         if (index != TCG_REG_NONE) {
                    815:             tcg_out_insn(s, RRE, AGR, TCG_TMP0, index);
                    816:         }
                    817:         index = TCG_TMP0;
                    818:     }
                    819: 
                    820:     if (opc_rx && ofs >= 0 && ofs < 0x1000) {
                    821:         tcg_out_insn_RX(s, opc_rx, data, base, index, ofs);
                    822:     } else {
                    823:         tcg_out_insn_RXY(s, opc_rxy, data, base, index, ofs);
                    824:     }
1.1       root      825: }
                    826: 
1.1.1.2   root      827: 
1.1       root      828: /* load data without address translation or endianness conversion */
1.1.1.2   root      829: static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
                    830:                               TCGReg base, tcg_target_long ofs)
1.1       root      831: {
1.1.1.2   root      832:     if (type == TCG_TYPE_I32) {
                    833:         tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
                    834:     } else {
                    835:         tcg_out_mem(s, 0, RXY_LG, data, base, TCG_REG_NONE, ofs);
                    836:     }
1.1       root      837: }
                    838: 
1.1.1.2   root      839: static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
                    840:                               TCGReg base, tcg_target_long ofs)
1.1       root      841: {
1.1.1.2   root      842:     if (type == TCG_TYPE_I32) {
                    843:         tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
                    844:     } else {
                    845:         tcg_out_mem(s, 0, RXY_STG, data, base, TCG_REG_NONE, ofs);
                    846:     }
                    847: }
                    848: 
                    849: /* load data from an absolute host address */
                    850: static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
                    851: {
                    852:     tcg_target_long addr = (tcg_target_long)abs;
                    853: 
                    854:     if (facilities & FACILITY_GEN_INST_EXT) {
                    855:         tcg_target_long disp = (addr - (tcg_target_long)s->code_ptr) >> 1;
                    856:         if (disp == (int32_t)disp) {
                    857:             if (type == TCG_TYPE_I32) {
                    858:                 tcg_out_insn(s, RIL, LRL, dest, disp);
                    859:             } else {
                    860:                 tcg_out_insn(s, RIL, LGRL, dest, disp);
                    861:             }
                    862:             return;
                    863:         }
                    864:     }
                    865: 
                    866:     tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
                    867:     tcg_out_ld(s, type, dest, dest, addr & 0xffff);
                    868: }
                    869: 
                    870: static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
                    871: {
                    872:     if (facilities & FACILITY_EXT_IMM) {
                    873:         tcg_out_insn(s, RRE, LGBR, dest, src);
                    874:         return;
                    875:     }
                    876: 
                    877:     if (type == TCG_TYPE_I32) {
                    878:         if (dest == src) {
                    879:             tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 24);
                    880:         } else {
                    881:             tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 24);
                    882:         }
                    883:         tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 24);
                    884:     } else {
                    885:         tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 56);
                    886:         tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 56);
                    887:     }
                    888: }
                    889: 
                    890: static void tgen_ext8u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
                    891: {
                    892:     if (facilities & FACILITY_EXT_IMM) {
                    893:         tcg_out_insn(s, RRE, LLGCR, dest, src);
                    894:         return;
                    895:     }
                    896: 
                    897:     if (dest == src) {
                    898:         tcg_out_movi(s, type, TCG_TMP0, 0xff);
                    899:         src = TCG_TMP0;
                    900:     } else {
                    901:         tcg_out_movi(s, type, dest, 0xff);
                    902:     }
                    903:     if (type == TCG_TYPE_I32) {
                    904:         tcg_out_insn(s, RR, NR, dest, src);
                    905:     } else {
                    906:         tcg_out_insn(s, RRE, NGR, dest, src);
                    907:     }
                    908: }
                    909: 
                    910: static void tgen_ext16s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
                    911: {
                    912:     if (facilities & FACILITY_EXT_IMM) {
                    913:         tcg_out_insn(s, RRE, LGHR, dest, src);
                    914:         return;
                    915:     }
                    916: 
                    917:     if (type == TCG_TYPE_I32) {
                    918:         if (dest == src) {
                    919:             tcg_out_sh32(s, RS_SLL, dest, TCG_REG_NONE, 16);
                    920:         } else {
                    921:             tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 16);
                    922:         }
                    923:         tcg_out_sh32(s, RS_SRA, dest, TCG_REG_NONE, 16);
                    924:     } else {
                    925:         tcg_out_sh64(s, RSY_SLLG, dest, src, TCG_REG_NONE, 48);
                    926:         tcg_out_sh64(s, RSY_SRAG, dest, dest, TCG_REG_NONE, 48);
                    927:     }
                    928: }
                    929: 
                    930: static void tgen_ext16u(TCGContext *s, TCGType type, TCGReg dest, TCGReg src)
                    931: {
                    932:     if (facilities & FACILITY_EXT_IMM) {
                    933:         tcg_out_insn(s, RRE, LLGHR, dest, src);
                    934:         return;
                    935:     }
                    936: 
                    937:     if (dest == src) {
                    938:         tcg_out_movi(s, type, TCG_TMP0, 0xffff);
                    939:         src = TCG_TMP0;
                    940:     } else {
                    941:         tcg_out_movi(s, type, dest, 0xffff);
                    942:     }
                    943:     if (type == TCG_TYPE_I32) {
                    944:         tcg_out_insn(s, RR, NR, dest, src);
                    945:     } else {
                    946:         tcg_out_insn(s, RRE, NGR, dest, src);
                    947:     }
                    948: }
                    949: 
                    950: static inline void tgen_ext32s(TCGContext *s, TCGReg dest, TCGReg src)
                    951: {
                    952:     tcg_out_insn(s, RRE, LGFR, dest, src);
                    953: }
                    954: 
                    955: static inline void tgen_ext32u(TCGContext *s, TCGReg dest, TCGReg src)
                    956: {
                    957:     tcg_out_insn(s, RRE, LLGFR, dest, src);
                    958: }
                    959: 
                    960: static inline void tgen32_addi(TCGContext *s, TCGReg dest, int32_t val)
                    961: {
                    962:     if (val == (int16_t)val) {
                    963:         tcg_out_insn(s, RI, AHI, dest, val);
                    964:     } else {
                    965:         tcg_out_insn(s, RIL, AFI, dest, val);
                    966:     }
                    967: }
                    968: 
                    969: static inline void tgen64_addi(TCGContext *s, TCGReg dest, int64_t val)
                    970: {
                    971:     if (val == (int16_t)val) {
                    972:         tcg_out_insn(s, RI, AGHI, dest, val);
                    973:     } else if (val == (int32_t)val) {
                    974:         tcg_out_insn(s, RIL, AGFI, dest, val);
                    975:     } else if (val == (uint32_t)val) {
                    976:         tcg_out_insn(s, RIL, ALGFI, dest, val);
                    977:     } else {
                    978:         tcg_abort();
                    979:     }
                    980: 
                    981: }
                    982: 
                    983: static void tgen64_andi(TCGContext *s, TCGReg dest, tcg_target_ulong val)
                    984: {
                    985:     static const S390Opcode ni_insns[4] = {
                    986:         RI_NILL, RI_NILH, RI_NIHL, RI_NIHH
                    987:     };
                    988:     static const S390Opcode nif_insns[2] = {
                    989:         RIL_NILF, RIL_NIHF
                    990:     };
                    991: 
                    992:     int i;
                    993: 
                    994:     /* Look for no-op.  */
                    995:     if (val == -1) {
                    996:         return;
                    997:     }
                    998: 
                    999:     /* Look for the zero-extensions.  */
                   1000:     if (val == 0xffffffff) {
                   1001:         tgen_ext32u(s, dest, dest);
                   1002:         return;
                   1003:     }
                   1004: 
                   1005:     if (facilities & FACILITY_EXT_IMM) {
                   1006:         if (val == 0xff) {
                   1007:             tgen_ext8u(s, TCG_TYPE_I64, dest, dest);
                   1008:             return;
                   1009:         }
                   1010:         if (val == 0xffff) {
                   1011:             tgen_ext16u(s, TCG_TYPE_I64, dest, dest);
                   1012:             return;
                   1013:         }
                   1014: 
                   1015:         /* Try all 32-bit insns that can perform it in one go.  */
                   1016:         for (i = 0; i < 4; i++) {
                   1017:             tcg_target_ulong mask = ~(0xffffull << i*16);
                   1018:             if ((val & mask) == mask) {
                   1019:                 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
                   1020:                 return;
                   1021:             }
                   1022:         }
                   1023: 
                   1024:         /* Try all 48-bit insns that can perform it in one go.  */
                   1025:         if (facilities & FACILITY_EXT_IMM) {
                   1026:             for (i = 0; i < 2; i++) {
                   1027:                 tcg_target_ulong mask = ~(0xffffffffull << i*32);
                   1028:                 if ((val & mask) == mask) {
                   1029:                     tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
                   1030:                     return;
                   1031:                 }
                   1032:             }
                   1033:         }
                   1034: 
                   1035:         /* Perform the AND via sequential modifications to the high and low
                   1036:            parts.  Do this via recursion to handle 16-bit vs 32-bit masks in
                   1037:            each half.  */
                   1038:         tgen64_andi(s, dest, val | 0xffffffff00000000ull);
                   1039:         tgen64_andi(s, dest, val | 0x00000000ffffffffull);
                   1040:     } else {
                   1041:         /* With no extended-immediate facility, just emit the sequence.  */
                   1042:         for (i = 0; i < 4; i++) {
                   1043:             tcg_target_ulong mask = 0xffffull << i*16;
                   1044:             if ((val & mask) != mask) {
                   1045:                 tcg_out_insn_RI(s, ni_insns[i], dest, val >> i*16);
                   1046:             }
                   1047:         }
                   1048:     }
                   1049: }
                   1050: 
                   1051: static void tgen64_ori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
                   1052: {
                   1053:     static const S390Opcode oi_insns[4] = {
                   1054:         RI_OILL, RI_OILH, RI_OIHL, RI_OIHH
                   1055:     };
                   1056:     static const S390Opcode nif_insns[2] = {
                   1057:         RIL_OILF, RIL_OIHF
                   1058:     };
                   1059: 
                   1060:     int i;
                   1061: 
                   1062:     /* Look for no-op.  */
                   1063:     if (val == 0) {
                   1064:         return;
                   1065:     }
                   1066: 
                   1067:     if (facilities & FACILITY_EXT_IMM) {
                   1068:         /* Try all 32-bit insns that can perform it in one go.  */
                   1069:         for (i = 0; i < 4; i++) {
                   1070:             tcg_target_ulong mask = (0xffffull << i*16);
                   1071:             if ((val & mask) != 0 && (val & ~mask) == 0) {
                   1072:                 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
                   1073:                 return;
                   1074:             }
                   1075:         }
                   1076: 
                   1077:         /* Try all 48-bit insns that can perform it in one go.  */
                   1078:         for (i = 0; i < 2; i++) {
                   1079:             tcg_target_ulong mask = (0xffffffffull << i*32);
                   1080:             if ((val & mask) != 0 && (val & ~mask) == 0) {
                   1081:                 tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);
                   1082:                 return;
                   1083:             }
                   1084:         }
                   1085: 
                   1086:         /* Perform the OR via sequential modifications to the high and
                   1087:            low parts.  Do this via recursion to handle 16-bit vs 32-bit
                   1088:            masks in each half.  */
                   1089:         tgen64_ori(s, dest, val & 0x00000000ffffffffull);
                   1090:         tgen64_ori(s, dest, val & 0xffffffff00000000ull);
                   1091:     } else {
                   1092:         /* With no extended-immediate facility, we don't need to be so
                   1093:            clever.  Just iterate over the insns and mask in the constant.  */
                   1094:         for (i = 0; i < 4; i++) {
                   1095:             tcg_target_ulong mask = (0xffffull << i*16);
                   1096:             if ((val & mask) != 0) {
                   1097:                 tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);
                   1098:             }
                   1099:         }
                   1100:     }
                   1101: }
                   1102: 
                   1103: static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val)
                   1104: {
                   1105:     /* Perform the xor by parts.  */
                   1106:     if (val & 0xffffffff) {
                   1107:         tcg_out_insn(s, RIL, XILF, dest, val);
                   1108:     }
                   1109:     if (val > 0xffffffff) {
                   1110:         tcg_out_insn(s, RIL, XIHF, dest, val >> 31 >> 1);
                   1111:     }
1.1       root     1112: }
                   1113: 
1.1.1.2   root     1114: static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
                   1115:                     TCGArg c2, int c2const)
                   1116: {
                   1117:     bool is_unsigned = (c > TCG_COND_GT);
                   1118:     if (c2const) {
                   1119:         if (c2 == 0) {
                   1120:             if (type == TCG_TYPE_I32) {
                   1121:                 tcg_out_insn(s, RR, LTR, r1, r1);
                   1122:             } else {
                   1123:                 tcg_out_insn(s, RRE, LTGR, r1, r1);
                   1124:             }
                   1125:             return tcg_cond_to_ltr_cond[c];
                   1126:         } else {
                   1127:             if (is_unsigned) {
                   1128:                 if (type == TCG_TYPE_I32) {
                   1129:                     tcg_out_insn(s, RIL, CLFI, r1, c2);
                   1130:                 } else {
                   1131:                     tcg_out_insn(s, RIL, CLGFI, r1, c2);
                   1132:                 }
                   1133:             } else {
                   1134:                 if (type == TCG_TYPE_I32) {
                   1135:                     tcg_out_insn(s, RIL, CFI, r1, c2);
                   1136:                 } else {
                   1137:                     tcg_out_insn(s, RIL, CGFI, r1, c2);
                   1138:                 }
                   1139:             }
                   1140:         }
                   1141:     } else {
                   1142:         if (is_unsigned) {
                   1143:             if (type == TCG_TYPE_I32) {
                   1144:                 tcg_out_insn(s, RR, CLR, r1, c2);
                   1145:             } else {
                   1146:                 tcg_out_insn(s, RRE, CLGR, r1, c2);
                   1147:             }
                   1148:         } else {
                   1149:             if (type == TCG_TYPE_I32) {
                   1150:                 tcg_out_insn(s, RR, CR, r1, c2);
                   1151:             } else {
                   1152:                 tcg_out_insn(s, RRE, CGR, r1, c2);
                   1153:             }
                   1154:         }
                   1155:     }
                   1156:     return tcg_cond_to_s390_cond[c];
                   1157: }
                   1158: 
                   1159: static void tgen_setcond(TCGContext *s, TCGType type, TCGCond c,
                   1160:                          TCGReg dest, TCGReg r1, TCGArg c2, int c2const)
                   1161: {
                   1162:     int cc = tgen_cmp(s, type, c, r1, c2, c2const);
                   1163: 
                   1164:     /* Emit: r1 = 1; if (cc) goto over; r1 = 0; over:  */
                   1165:     tcg_out_movi(s, type, dest, 1);
                   1166:     tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);
                   1167:     tcg_out_movi(s, type, dest, 0);
                   1168: }
                   1169: 
                   1170: static void tgen_gotoi(TCGContext *s, int cc, tcg_target_long dest)
                   1171: {
                   1172:     tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
                   1173:     if (off > -0x8000 && off < 0x7fff) {
                   1174:         tcg_out_insn(s, RI, BRC, cc, off);
                   1175:     } else if (off == (int32_t)off) {
                   1176:         tcg_out_insn(s, RIL, BRCL, cc, off);
                   1177:     } else {
                   1178:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
                   1179:         tcg_out_insn(s, RR, BCR, cc, TCG_TMP0);
                   1180:     }
                   1181: }
                   1182: 
                   1183: static void tgen_branch(TCGContext *s, int cc, int labelno)
                   1184: {
                   1185:     TCGLabel* l = &s->labels[labelno];
                   1186:     if (l->has_value) {
                   1187:         tgen_gotoi(s, cc, l->u.value);
                   1188:     } else if (USE_LONG_BRANCHES) {
                   1189:         tcg_out16(s, RIL_BRCL | (cc << 4));
                   1190:         tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, labelno, -2);
                   1191:         s->code_ptr += 4;
                   1192:     } else {
                   1193:         tcg_out16(s, RI_BRC | (cc << 4));
                   1194:         tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, labelno, -2);
                   1195:         s->code_ptr += 2;
                   1196:     }
                   1197: }
                   1198: 
                   1199: static void tgen_compare_branch(TCGContext *s, S390Opcode opc, int cc,
                   1200:                                 TCGReg r1, TCGReg r2, int labelno)
                   1201: {
                   1202:     TCGLabel* l = &s->labels[labelno];
                   1203:     tcg_target_long off;
                   1204: 
                   1205:     if (l->has_value) {
                   1206:         off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
                   1207:     } else {
                   1208:         /* We need to keep the offset unchanged for retranslation.  */
                   1209:         off = ((int16_t *)s->code_ptr)[1];
                   1210:         tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
                   1211:     }
                   1212: 
                   1213:     tcg_out16(s, (opc & 0xff00) | (r1 << 4) | r2);
                   1214:     tcg_out16(s, off);
                   1215:     tcg_out16(s, cc << 12 | (opc & 0xff));
                   1216: }
                   1217: 
                   1218: static void tgen_compare_imm_branch(TCGContext *s, S390Opcode opc, int cc,
                   1219:                                     TCGReg r1, int i2, int labelno)
                   1220: {
                   1221:     TCGLabel* l = &s->labels[labelno];
                   1222:     tcg_target_long off;
                   1223: 
                   1224:     if (l->has_value) {
                   1225:         off = (l->u.value - (tcg_target_long)s->code_ptr) >> 1;
                   1226:     } else {
                   1227:         /* We need to keep the offset unchanged for retranslation.  */
                   1228:         off = ((int16_t *)s->code_ptr)[1];
                   1229:         tcg_out_reloc(s, s->code_ptr + 2, R_390_PC16DBL, labelno, -2);
                   1230:     }
                   1231: 
                   1232:     tcg_out16(s, (opc & 0xff00) | (r1 << 4) | cc);
                   1233:     tcg_out16(s, off);
                   1234:     tcg_out16(s, (i2 << 8) | (opc & 0xff));
                   1235: }
                   1236: 
                   1237: static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
                   1238:                         TCGReg r1, TCGArg c2, int c2const, int labelno)
                   1239: {
                   1240:     int cc;
                   1241: 
                   1242:     if (facilities & FACILITY_GEN_INST_EXT) {
                   1243:         bool is_unsigned = (c > TCG_COND_GT);
                   1244:         bool in_range;
                   1245:         S390Opcode opc;
                   1246: 
                   1247:         cc = tcg_cond_to_s390_cond[c];
                   1248: 
                   1249:         if (!c2const) {
                   1250:             opc = (type == TCG_TYPE_I32
                   1251:                    ? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
                   1252:                    : (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
                   1253:             tgen_compare_branch(s, opc, cc, r1, c2, labelno);
                   1254:             return;
                   1255:         }
                   1256: 
                   1257:         /* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
                   1258:            If the immediate we've been given does not fit that range, we'll
                   1259:            fall back to separate compare and branch instructions using the
                   1260:            larger comparison range afforded by COMPARE IMMEDIATE.  */
                   1261:         if (type == TCG_TYPE_I32) {
                   1262:             if (is_unsigned) {
                   1263:                 opc = RIE_CLIJ;
                   1264:                 in_range = (uint32_t)c2 == (uint8_t)c2;
                   1265:             } else {
                   1266:                 opc = RIE_CIJ;
                   1267:                 in_range = (int32_t)c2 == (int8_t)c2;
                   1268:             }
                   1269:         } else {
                   1270:             if (is_unsigned) {
                   1271:                 opc = RIE_CLGIJ;
                   1272:                 in_range = (uint64_t)c2 == (uint8_t)c2;
                   1273:             } else {
                   1274:                 opc = RIE_CGIJ;
                   1275:                 in_range = (int64_t)c2 == (int8_t)c2;
                   1276:             }
                   1277:         }
                   1278:         if (in_range) {
                   1279:             tgen_compare_imm_branch(s, opc, cc, r1, c2, labelno);
                   1280:             return;
                   1281:         }
                   1282:     }
                   1283: 
                   1284:     cc = tgen_cmp(s, type, c, r1, c2, c2const);
                   1285:     tgen_branch(s, cc, labelno);
                   1286: }
                   1287: 
                   1288: static void tgen_calli(TCGContext *s, tcg_target_long dest)
                   1289: {
                   1290:     tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
                   1291:     if (off == (int32_t)off) {
                   1292:         tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
                   1293:     } else {
                   1294:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_TMP0, dest);
                   1295:         tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_TMP0);
                   1296:     }
                   1297: }
                   1298: 
                   1299: static void tcg_out_qemu_ld_direct(TCGContext *s, int opc, TCGReg data,
                   1300:                                    TCGReg base, TCGReg index, int disp)
                   1301: {
                   1302: #ifdef TARGET_WORDS_BIGENDIAN
                   1303:     const int bswap = 0;
                   1304: #else
                   1305:     const int bswap = 1;
                   1306: #endif
                   1307:     switch (opc) {
                   1308:     case LD_UINT8:
                   1309:         tcg_out_insn(s, RXY, LLGC, data, base, index, disp);
                   1310:         break;
                   1311:     case LD_INT8:
                   1312:         tcg_out_insn(s, RXY, LGB, data, base, index, disp);
                   1313:         break;
                   1314:     case LD_UINT16:
                   1315:         if (bswap) {
                   1316:             /* swapped unsigned halfword load with upper bits zeroed */
                   1317:             tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
                   1318:             tgen_ext16u(s, TCG_TYPE_I64, data, data);
                   1319:         } else {
                   1320:             tcg_out_insn(s, RXY, LLGH, data, base, index, disp);
                   1321:         }
                   1322:         break;
                   1323:     case LD_INT16:
                   1324:         if (bswap) {
                   1325:             /* swapped sign-extended halfword load */
                   1326:             tcg_out_insn(s, RXY, LRVH, data, base, index, disp);
                   1327:             tgen_ext16s(s, TCG_TYPE_I64, data, data);
                   1328:         } else {
                   1329:             tcg_out_insn(s, RXY, LGH, data, base, index, disp);
                   1330:         }
                   1331:         break;
                   1332:     case LD_UINT32:
                   1333:         if (bswap) {
                   1334:             /* swapped unsigned int load with upper bits zeroed */
                   1335:             tcg_out_insn(s, RXY, LRV, data, base, index, disp);
                   1336:             tgen_ext32u(s, data, data);
                   1337:         } else {
                   1338:             tcg_out_insn(s, RXY, LLGF, data, base, index, disp);
                   1339:         }
                   1340:         break;
                   1341:     case LD_INT32:
                   1342:         if (bswap) {
                   1343:             /* swapped sign-extended int load */
                   1344:             tcg_out_insn(s, RXY, LRV, data, base, index, disp);
                   1345:             tgen_ext32s(s, data, data);
                   1346:         } else {
                   1347:             tcg_out_insn(s, RXY, LGF, data, base, index, disp);
                   1348:         }
                   1349:         break;
                   1350:     case LD_UINT64:
                   1351:         if (bswap) {
                   1352:             tcg_out_insn(s, RXY, LRVG, data, base, index, disp);
                   1353:         } else {
                   1354:             tcg_out_insn(s, RXY, LG, data, base, index, disp);
                   1355:         }
                   1356:         break;
                   1357:     default:
                   1358:         tcg_abort();
                   1359:     }
                   1360: }
                   1361: 
                   1362: static void tcg_out_qemu_st_direct(TCGContext *s, int opc, TCGReg data,
                   1363:                                    TCGReg base, TCGReg index, int disp)
                   1364: {
                   1365: #ifdef TARGET_WORDS_BIGENDIAN
                   1366:     const int bswap = 0;
                   1367: #else
                   1368:     const int bswap = 1;
                   1369: #endif
                   1370:     switch (opc) {
                   1371:     case LD_UINT8:
                   1372:         if (disp >= 0 && disp < 0x1000) {
                   1373:             tcg_out_insn(s, RX, STC, data, base, index, disp);
                   1374:         } else {
                   1375:             tcg_out_insn(s, RXY, STCY, data, base, index, disp);
                   1376:         }
                   1377:         break;
                   1378:     case LD_UINT16:
                   1379:         if (bswap) {
                   1380:             tcg_out_insn(s, RXY, STRVH, data, base, index, disp);
                   1381:         } else if (disp >= 0 && disp < 0x1000) {
                   1382:             tcg_out_insn(s, RX, STH, data, base, index, disp);
                   1383:         } else {
                   1384:             tcg_out_insn(s, RXY, STHY, data, base, index, disp);
                   1385:         }
                   1386:         break;
                   1387:     case LD_UINT32:
                   1388:         if (bswap) {
                   1389:             tcg_out_insn(s, RXY, STRV, data, base, index, disp);
                   1390:         } else if (disp >= 0 && disp < 0x1000) {
                   1391:             tcg_out_insn(s, RX, ST, data, base, index, disp);
                   1392:         } else {
                   1393:             tcg_out_insn(s, RXY, STY, data, base, index, disp);
                   1394:         }
                   1395:         break;
                   1396:     case LD_UINT64:
                   1397:         if (bswap) {
                   1398:             tcg_out_insn(s, RXY, STRVG, data, base, index, disp);
                   1399:         } else {
                   1400:             tcg_out_insn(s, RXY, STG, data, base, index, disp);
                   1401:         }
                   1402:         break;
                   1403:     default:
                   1404:         tcg_abort();
                   1405:     }
                   1406: }
                   1407: 
                   1408: #if defined(CONFIG_SOFTMMU)
                   1409: static void tgen64_andi_tmp(TCGContext *s, TCGReg dest, tcg_target_ulong val)
                   1410: {
                   1411:     if (tcg_match_andi(0, val)) {
                   1412:         tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, val);
                   1413:         tcg_out_insn(s, RRE, NGR, dest, TCG_TMP0);
                   1414:     } else {
                   1415:         tgen64_andi(s, dest, val);
                   1416:     }
                   1417: }
                   1418: 
                   1419: static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
                   1420:                                   TCGReg addr_reg, int mem_index, int opc,
                   1421:                                   uint16_t **label2_ptr_p, int is_store)
                   1422: {
                   1423:     const TCGReg arg0 = TCG_REG_R2;
                   1424:     const TCGReg arg1 = TCG_REG_R3;
                   1425:     int s_bits = opc & 3;
                   1426:     uint16_t *label1_ptr;
                   1427:     tcg_target_long ofs;
                   1428: 
                   1429:     if (TARGET_LONG_BITS == 32) {
                   1430:         tgen_ext32u(s, arg0, addr_reg);
                   1431:     } else {
                   1432:         tcg_out_mov(s, TCG_TYPE_I64, arg0, addr_reg);
                   1433:     }
                   1434: 
                   1435:     tcg_out_sh64(s, RSY_SRLG, arg1, addr_reg, TCG_REG_NONE,
                   1436:                  TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
                   1437: 
                   1438:     tgen64_andi_tmp(s, arg0, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
                   1439:     tgen64_andi_tmp(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
                   1440: 
                   1441:     if (is_store) {
                   1442:         ofs = offsetof(CPUState, tlb_table[mem_index][0].addr_write);
                   1443:     } else {
                   1444:         ofs = offsetof(CPUState, tlb_table[mem_index][0].addr_read);
                   1445:     }
                   1446:     assert(ofs < 0x80000);
                   1447: 
                   1448:     if (TARGET_LONG_BITS == 32) {
                   1449:         tcg_out_mem(s, RX_C, RXY_CY, arg0, arg1, TCG_AREG0, ofs);
                   1450:     } else {
                   1451:         tcg_out_mem(s, 0, RXY_CG, arg0, arg1, TCG_AREG0, ofs);
                   1452:     }
                   1453: 
                   1454:     if (TARGET_LONG_BITS == 32) {
                   1455:         tgen_ext32u(s, arg0, addr_reg);
                   1456:     } else {
                   1457:         tcg_out_mov(s, TCG_TYPE_I64, arg0, addr_reg);
                   1458:     }
                   1459: 
                   1460:     label1_ptr = (uint16_t*)s->code_ptr;
                   1461: 
                   1462:     /* je label1 (offset will be patched in later) */
                   1463:     tcg_out_insn(s, RI, BRC, S390_CC_EQ, 0);
                   1464: 
                   1465:     /* call load/store helper */
                   1466:     if (is_store) {
                   1467:         /* Make sure to zero-extend the value to the full register
                   1468:            for the calling convention.  */
                   1469:         switch (opc) {
                   1470:         case LD_UINT8:
                   1471:             tgen_ext8u(s, TCG_TYPE_I64, arg1, data_reg);
                   1472:             break;
                   1473:         case LD_UINT16:
                   1474:             tgen_ext16u(s, TCG_TYPE_I64, arg1, data_reg);
                   1475:             break;
                   1476:         case LD_UINT32:
                   1477:             tgen_ext32u(s, arg1, data_reg);
                   1478:             break;
                   1479:         case LD_UINT64:
                   1480:             tcg_out_mov(s, TCG_TYPE_I64, arg1, data_reg);
                   1481:             break;
                   1482:         default:
                   1483:             tcg_abort();
                   1484:         }
                   1485:         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
                   1486:         tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
                   1487:     } else {
                   1488:         tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
                   1489:         tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
                   1490: 
                   1491:         /* sign extension */
                   1492:         switch (opc) {
                   1493:         case LD_INT8:
                   1494:             tgen_ext8s(s, TCG_TYPE_I64, data_reg, arg0);
                   1495:             break;
                   1496:         case LD_INT16:
                   1497:             tgen_ext16s(s, TCG_TYPE_I64, data_reg, arg0);
                   1498:             break;
                   1499:         case LD_INT32:
                   1500:             tgen_ext32s(s, data_reg, arg0);
                   1501:             break;
                   1502:         default:
                   1503:             /* unsigned -> just copy */
                   1504:             tcg_out_mov(s, TCG_TYPE_I64, data_reg, arg0);
                   1505:             break;
                   1506:         }
                   1507:     }
                   1508: 
                   1509:     /* jump to label2 (end) */
                   1510:     *label2_ptr_p = (uint16_t*)s->code_ptr;
                   1511: 
                   1512:     tcg_out_insn(s, RI, BRC, S390_CC_ALWAYS, 0);
                   1513: 
                   1514:     /* this is label1, patch branch */
                   1515:     *(label1_ptr + 1) = ((unsigned long)s->code_ptr -
                   1516:                          (unsigned long)label1_ptr) >> 1;
                   1517: 
                   1518:     ofs = offsetof(CPUState, tlb_table[mem_index][0].addend);
                   1519:     assert(ofs < 0x80000);
                   1520: 
                   1521:     tcg_out_mem(s, 0, RXY_AG, arg0, arg1, TCG_AREG0, ofs);
                   1522: }
                   1523: 
                   1524: static void tcg_finish_qemu_ldst(TCGContext* s, uint16_t *label2_ptr)
                   1525: {
                   1526:     /* patch branch */
                   1527:     *(label2_ptr + 1) = ((unsigned long)s->code_ptr -
                   1528:                          (unsigned long)label2_ptr) >> 1;
                   1529: }
                   1530: #else
                   1531: static void tcg_prepare_user_ldst(TCGContext *s, TCGReg *addr_reg,
                   1532:                                   TCGReg *index_reg, tcg_target_long *disp)
                   1533: {
                   1534:     if (TARGET_LONG_BITS == 32) {
                   1535:         tgen_ext32u(s, TCG_TMP0, *addr_reg);
                   1536:         *addr_reg = TCG_TMP0;
                   1537:     }
                   1538:     if (GUEST_BASE < 0x80000) {
                   1539:         *index_reg = TCG_REG_NONE;
                   1540:         *disp = GUEST_BASE;
                   1541:     } else {
                   1542:         *index_reg = TCG_GUEST_BASE_REG;
                   1543:         *disp = 0;
                   1544:     }
                   1545: }
                   1546: #endif /* CONFIG_SOFTMMU */
                   1547: 
                   1548: /* load data with address translation (if applicable)
                   1549:    and endianness conversion */
                   1550: static void tcg_out_qemu_ld(TCGContext* s, const TCGArg* args, int opc)
                   1551: {
                   1552:     TCGReg addr_reg, data_reg;
                   1553: #if defined(CONFIG_SOFTMMU)
                   1554:     int mem_index;
                   1555:     uint16_t *label2_ptr;
                   1556: #else
                   1557:     TCGReg index_reg;
                   1558:     tcg_target_long disp;
                   1559: #endif
                   1560: 
                   1561:     data_reg = *args++;
                   1562:     addr_reg = *args++;
                   1563: 
                   1564: #if defined(CONFIG_SOFTMMU)
                   1565:     mem_index = *args;
                   1566: 
                   1567:     tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
                   1568:                           opc, &label2_ptr, 0);
                   1569: 
                   1570:     tcg_out_qemu_ld_direct(s, opc, data_reg, TCG_REG_R2, TCG_REG_NONE, 0);
                   1571: 
                   1572:     tcg_finish_qemu_ldst(s, label2_ptr);
                   1573: #else
                   1574:     tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
                   1575:     tcg_out_qemu_ld_direct(s, opc, data_reg, addr_reg, index_reg, disp);
                   1576: #endif
                   1577: }
                   1578: 
                   1579: static void tcg_out_qemu_st(TCGContext* s, const TCGArg* args, int opc)
                   1580: {
                   1581:     TCGReg addr_reg, data_reg;
                   1582: #if defined(CONFIG_SOFTMMU)
                   1583:     int mem_index;
                   1584:     uint16_t *label2_ptr;
                   1585: #else
                   1586:     TCGReg index_reg;
                   1587:     tcg_target_long disp;
                   1588: #endif
                   1589: 
                   1590:     data_reg = *args++;
                   1591:     addr_reg = *args++;
                   1592: 
                   1593: #if defined(CONFIG_SOFTMMU)
                   1594:     mem_index = *args;
                   1595: 
                   1596:     tcg_prepare_qemu_ldst(s, data_reg, addr_reg, mem_index,
                   1597:                           opc, &label2_ptr, 1);
                   1598: 
                   1599:     tcg_out_qemu_st_direct(s, opc, data_reg, TCG_REG_R2, TCG_REG_NONE, 0);
                   1600: 
                   1601:     tcg_finish_qemu_ldst(s, label2_ptr);
                   1602: #else
                   1603:     tcg_prepare_user_ldst(s, &addr_reg, &index_reg, &disp);
                   1604:     tcg_out_qemu_st_direct(s, opc, data_reg, addr_reg, index_reg, disp);
                   1605: #endif
                   1606: }
                   1607: 
                   1608: #if TCG_TARGET_REG_BITS == 64
                   1609: # define OP_32_64(x) \
                   1610:         case glue(glue(INDEX_op_,x),_i32): \
                   1611:         case glue(glue(INDEX_op_,x),_i64)
                   1612: #else
                   1613: # define OP_32_64(x) \
                   1614:         case glue(glue(INDEX_op_,x),_i32)
                   1615: #endif
                   1616: 
                   1617: static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
1.1       root     1618:                 const TCGArg *args, const int *const_args)
                   1619: {
1.1.1.2   root     1620:     S390Opcode op;
                   1621: 
                   1622:     switch (opc) {
                   1623:     case INDEX_op_exit_tb:
                   1624:         /* return value */
                   1625:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R2, args[0]);
                   1626:         tgen_gotoi(s, S390_CC_ALWAYS, (unsigned long)tb_ret_addr);
                   1627:         break;
                   1628: 
                   1629:     case INDEX_op_goto_tb:
                   1630:         if (s->tb_jmp_offset) {
                   1631:             tcg_abort();
                   1632:         } else {
                   1633:             /* load address stored at s->tb_next + args[0] */
                   1634:             tcg_out_ld_abs(s, TCG_TYPE_PTR, TCG_TMP0, s->tb_next + args[0]);
                   1635:             /* and go there */
                   1636:             tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_TMP0);
                   1637:         }
                   1638:         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
                   1639:         break;
                   1640: 
                   1641:     case INDEX_op_call:
                   1642:         if (const_args[0]) {
                   1643:             tgen_calli(s, args[0]);
                   1644:         } else {
                   1645:             tcg_out_insn(s, RR, BASR, TCG_REG_R14, args[0]);
                   1646:         }
                   1647:         break;
                   1648: 
                   1649:     case INDEX_op_mov_i32:
                   1650:         tcg_out_mov(s, TCG_TYPE_I32, args[0], args[1]);
                   1651:         break;
                   1652:     case INDEX_op_movi_i32:
                   1653:         tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]);
                   1654:         break;
                   1655: 
                   1656:     OP_32_64(ld8u):
                   1657:         /* ??? LLC (RXY format) is only present with the extended-immediate
                   1658:            facility, whereas LLGC is always present.  */
                   1659:         tcg_out_mem(s, 0, RXY_LLGC, args[0], args[1], TCG_REG_NONE, args[2]);
                   1660:         break;
                   1661: 
                   1662:     OP_32_64(ld8s):
                   1663:         /* ??? LB is no smaller than LGB, so no point to using it.  */
                   1664:         tcg_out_mem(s, 0, RXY_LGB, args[0], args[1], TCG_REG_NONE, args[2]);
                   1665:         break;
                   1666: 
                   1667:     OP_32_64(ld16u):
                   1668:         /* ??? LLH (RXY format) is only present with the extended-immediate
                   1669:            facility, whereas LLGH is always present.  */
                   1670:         tcg_out_mem(s, 0, RXY_LLGH, args[0], args[1], TCG_REG_NONE, args[2]);
                   1671:         break;
                   1672: 
                   1673:     case INDEX_op_ld16s_i32:
                   1674:         tcg_out_mem(s, RX_LH, RXY_LHY, args[0], args[1], TCG_REG_NONE, args[2]);
                   1675:         break;
                   1676: 
                   1677:     case INDEX_op_ld_i32:
                   1678:         tcg_out_ld(s, TCG_TYPE_I32, args[0], args[1], args[2]);
                   1679:         break;
                   1680: 
                   1681:     OP_32_64(st8):
                   1682:         tcg_out_mem(s, RX_STC, RXY_STCY, args[0], args[1],
                   1683:                     TCG_REG_NONE, args[2]);
                   1684:         break;
                   1685: 
                   1686:     OP_32_64(st16):
                   1687:         tcg_out_mem(s, RX_STH, RXY_STHY, args[0], args[1],
                   1688:                     TCG_REG_NONE, args[2]);
                   1689:         break;
                   1690: 
                   1691:     case INDEX_op_st_i32:
                   1692:         tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
                   1693:         break;
                   1694: 
                   1695:     case INDEX_op_add_i32:
                   1696:         if (const_args[2]) {
                   1697:             tgen32_addi(s, args[0], args[2]);
                   1698:         } else {
                   1699:             tcg_out_insn(s, RR, AR, args[0], args[2]);
                   1700:         }
                   1701:         break;
                   1702:     case INDEX_op_sub_i32:
                   1703:         if (const_args[2]) {
                   1704:             tgen32_addi(s, args[0], -args[2]);
                   1705:         } else {
                   1706:             tcg_out_insn(s, RR, SR, args[0], args[2]);
                   1707:         }
                   1708:         break;
                   1709: 
                   1710:     case INDEX_op_and_i32:
                   1711:         if (const_args[2]) {
                   1712:             tgen64_andi(s, args[0], args[2] | 0xffffffff00000000ull);
                   1713:         } else {
                   1714:             tcg_out_insn(s, RR, NR, args[0], args[2]);
                   1715:         }
                   1716:         break;
                   1717:     case INDEX_op_or_i32:
                   1718:         if (const_args[2]) {
                   1719:             tgen64_ori(s, args[0], args[2] & 0xffffffff);
                   1720:         } else {
                   1721:             tcg_out_insn(s, RR, OR, args[0], args[2]);
                   1722:         }
                   1723:         break;
                   1724:     case INDEX_op_xor_i32:
                   1725:         if (const_args[2]) {
                   1726:             tgen64_xori(s, args[0], args[2] & 0xffffffff);
                   1727:         } else {
                   1728:             tcg_out_insn(s, RR, XR, args[0], args[2]);
                   1729:         }
                   1730:         break;
                   1731: 
                   1732:     case INDEX_op_neg_i32:
                   1733:         tcg_out_insn(s, RR, LCR, args[0], args[1]);
                   1734:         break;
                   1735: 
                   1736:     case INDEX_op_mul_i32:
                   1737:         if (const_args[2]) {
                   1738:             if ((int32_t)args[2] == (int16_t)args[2]) {
                   1739:                 tcg_out_insn(s, RI, MHI, args[0], args[2]);
                   1740:             } else {
                   1741:                 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
                   1742:             }
                   1743:         } else {
                   1744:             tcg_out_insn(s, RRE, MSR, args[0], args[2]);
                   1745:         }
                   1746:         break;
                   1747: 
                   1748:     case INDEX_op_div2_i32:
                   1749:         tcg_out_insn(s, RR, DR, TCG_REG_R2, args[4]);
                   1750:         break;
                   1751:     case INDEX_op_divu2_i32:
                   1752:         tcg_out_insn(s, RRE, DLR, TCG_REG_R2, args[4]);
                   1753:         break;
                   1754: 
                   1755:     case INDEX_op_shl_i32:
                   1756:         op = RS_SLL;
                   1757:     do_shift32:
                   1758:         if (const_args[2]) {
                   1759:             tcg_out_sh32(s, op, args[0], TCG_REG_NONE, args[2]);
                   1760:         } else {
                   1761:             tcg_out_sh32(s, op, args[0], args[2], 0);
                   1762:         }
                   1763:         break;
                   1764:     case INDEX_op_shr_i32:
                   1765:         op = RS_SRL;
                   1766:         goto do_shift32;
                   1767:     case INDEX_op_sar_i32:
                   1768:         op = RS_SRA;
                   1769:         goto do_shift32;
                   1770: 
                   1771:     case INDEX_op_rotl_i32:
                   1772:         /* ??? Using tcg_out_sh64 here for the format; it is a 32-bit rol.  */
                   1773:         if (const_args[2]) {
                   1774:             tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_REG_NONE, args[2]);
                   1775:         } else {
                   1776:             tcg_out_sh64(s, RSY_RLL, args[0], args[1], args[2], 0);
                   1777:         }
                   1778:         break;
                   1779:     case INDEX_op_rotr_i32:
                   1780:         if (const_args[2]) {
                   1781:             tcg_out_sh64(s, RSY_RLL, args[0], args[1],
                   1782:                          TCG_REG_NONE, (32 - args[2]) & 31);
                   1783:         } else {
                   1784:             tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
                   1785:             tcg_out_sh64(s, RSY_RLL, args[0], args[1], TCG_TMP0, 0);
                   1786:         }
                   1787:         break;
                   1788: 
                   1789:     case INDEX_op_ext8s_i32:
                   1790:         tgen_ext8s(s, TCG_TYPE_I32, args[0], args[1]);
                   1791:         break;
                   1792:     case INDEX_op_ext16s_i32:
                   1793:         tgen_ext16s(s, TCG_TYPE_I32, args[0], args[1]);
                   1794:         break;
                   1795:     case INDEX_op_ext8u_i32:
                   1796:         tgen_ext8u(s, TCG_TYPE_I32, args[0], args[1]);
                   1797:         break;
                   1798:     case INDEX_op_ext16u_i32:
                   1799:         tgen_ext16u(s, TCG_TYPE_I32, args[0], args[1]);
                   1800:         break;
                   1801: 
                   1802:     OP_32_64(bswap16):
                   1803:         /* The TCG bswap definition requires bits 0-47 already be zero.
                   1804:            Thus we don't need the G-type insns to implement bswap16_i64.  */
                   1805:         tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
                   1806:         tcg_out_sh32(s, RS_SRL, args[0], TCG_REG_NONE, 16);
                   1807:         break;
                   1808:     OP_32_64(bswap32):
                   1809:         tcg_out_insn(s, RRE, LRVR, args[0], args[1]);
                   1810:         break;
                   1811: 
                   1812:     case INDEX_op_br:
                   1813:         tgen_branch(s, S390_CC_ALWAYS, args[0]);
                   1814:         break;
                   1815: 
                   1816:     case INDEX_op_brcond_i32:
                   1817:         tgen_brcond(s, TCG_TYPE_I32, args[2], args[0],
                   1818:                     args[1], const_args[1], args[3]);
                   1819:         break;
                   1820:     case INDEX_op_setcond_i32:
                   1821:         tgen_setcond(s, TCG_TYPE_I32, args[3], args[0], args[1],
                   1822:                      args[2], const_args[2]);
                   1823:         break;
                   1824: 
                   1825:     case INDEX_op_qemu_ld8u:
                   1826:         tcg_out_qemu_ld(s, args, LD_UINT8);
                   1827:         break;
                   1828:     case INDEX_op_qemu_ld8s:
                   1829:         tcg_out_qemu_ld(s, args, LD_INT8);
                   1830:         break;
                   1831:     case INDEX_op_qemu_ld16u:
                   1832:         tcg_out_qemu_ld(s, args, LD_UINT16);
                   1833:         break;
                   1834:     case INDEX_op_qemu_ld16s:
                   1835:         tcg_out_qemu_ld(s, args, LD_INT16);
                   1836:         break;
                   1837:     case INDEX_op_qemu_ld32:
                   1838:         /* ??? Technically we can use a non-extending instruction.  */
                   1839:         tcg_out_qemu_ld(s, args, LD_UINT32);
                   1840:         break;
                   1841:     case INDEX_op_qemu_ld64:
                   1842:         tcg_out_qemu_ld(s, args, LD_UINT64);
                   1843:         break;
                   1844: 
                   1845:     case INDEX_op_qemu_st8:
                   1846:         tcg_out_qemu_st(s, args, LD_UINT8);
                   1847:         break;
                   1848:     case INDEX_op_qemu_st16:
                   1849:         tcg_out_qemu_st(s, args, LD_UINT16);
                   1850:         break;
                   1851:     case INDEX_op_qemu_st32:
                   1852:         tcg_out_qemu_st(s, args, LD_UINT32);
                   1853:         break;
                   1854:     case INDEX_op_qemu_st64:
                   1855:         tcg_out_qemu_st(s, args, LD_UINT64);
                   1856:         break;
                   1857: 
                   1858: #if TCG_TARGET_REG_BITS == 64
                   1859:     case INDEX_op_mov_i64:
                   1860:         tcg_out_mov(s, TCG_TYPE_I64, args[0], args[1]);
                   1861:         break;
                   1862:     case INDEX_op_movi_i64:
                   1863:         tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
                   1864:         break;
                   1865: 
                   1866:     case INDEX_op_ld16s_i64:
                   1867:         tcg_out_mem(s, 0, RXY_LGH, args[0], args[1], TCG_REG_NONE, args[2]);
                   1868:         break;
                   1869:     case INDEX_op_ld32u_i64:
                   1870:         tcg_out_mem(s, 0, RXY_LLGF, args[0], args[1], TCG_REG_NONE, args[2]);
                   1871:         break;
                   1872:     case INDEX_op_ld32s_i64:
                   1873:         tcg_out_mem(s, 0, RXY_LGF, args[0], args[1], TCG_REG_NONE, args[2]);
                   1874:         break;
                   1875:     case INDEX_op_ld_i64:
                   1876:         tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
                   1877:         break;
                   1878: 
                   1879:     case INDEX_op_st32_i64:
                   1880:         tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
                   1881:         break;
                   1882:     case INDEX_op_st_i64:
                   1883:         tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
                   1884:         break;
                   1885: 
                   1886:     case INDEX_op_add_i64:
                   1887:         if (const_args[2]) {
                   1888:             tgen64_addi(s, args[0], args[2]);
                   1889:         } else {
                   1890:             tcg_out_insn(s, RRE, AGR, args[0], args[2]);
                   1891:         }
                   1892:         break;
                   1893:     case INDEX_op_sub_i64:
                   1894:         if (const_args[2]) {
                   1895:             tgen64_addi(s, args[0], -args[2]);
                   1896:         } else {
                   1897:             tcg_out_insn(s, RRE, SGR, args[0], args[2]);
                   1898:         }
                   1899:         break;
                   1900: 
                   1901:     case INDEX_op_and_i64:
                   1902:         if (const_args[2]) {
                   1903:             tgen64_andi(s, args[0], args[2]);
                   1904:         } else {
                   1905:             tcg_out_insn(s, RRE, NGR, args[0], args[2]);
                   1906:         }
                   1907:         break;
                   1908:     case INDEX_op_or_i64:
                   1909:         if (const_args[2]) {
                   1910:             tgen64_ori(s, args[0], args[2]);
                   1911:         } else {
                   1912:             tcg_out_insn(s, RRE, OGR, args[0], args[2]);
                   1913:         }
                   1914:         break;
                   1915:     case INDEX_op_xor_i64:
                   1916:         if (const_args[2]) {
                   1917:             tgen64_xori(s, args[0], args[2]);
                   1918:         } else {
                   1919:             tcg_out_insn(s, RRE, XGR, args[0], args[2]);
                   1920:         }
                   1921:         break;
                   1922: 
                   1923:     case INDEX_op_neg_i64:
                   1924:         tcg_out_insn(s, RRE, LCGR, args[0], args[1]);
                   1925:         break;
                   1926:     case INDEX_op_bswap64_i64:
                   1927:         tcg_out_insn(s, RRE, LRVGR, args[0], args[1]);
                   1928:         break;
                   1929: 
                   1930:     case INDEX_op_mul_i64:
                   1931:         if (const_args[2]) {
                   1932:             if (args[2] == (int16_t)args[2]) {
                   1933:                 tcg_out_insn(s, RI, MGHI, args[0], args[2]);
                   1934:             } else {
                   1935:                 tcg_out_insn(s, RIL, MSGFI, args[0], args[2]);
                   1936:             }
                   1937:         } else {
                   1938:             tcg_out_insn(s, RRE, MSGR, args[0], args[2]);
                   1939:         }
                   1940:         break;
                   1941: 
                   1942:     case INDEX_op_div2_i64:
                   1943:         /* ??? We get an unnecessary sign-extension of the dividend
                   1944:            into R3 with this definition, but as we do in fact always
                   1945:            produce both quotient and remainder using INDEX_op_div_i64
                   1946:            instead requires jumping through even more hoops.  */
                   1947:         tcg_out_insn(s, RRE, DSGR, TCG_REG_R2, args[4]);
                   1948:         break;
                   1949:     case INDEX_op_divu2_i64:
                   1950:         tcg_out_insn(s, RRE, DLGR, TCG_REG_R2, args[4]);
                   1951:         break;
                   1952: 
                   1953:     case INDEX_op_shl_i64:
                   1954:         op = RSY_SLLG;
                   1955:     do_shift64:
                   1956:         if (const_args[2]) {
                   1957:             tcg_out_sh64(s, op, args[0], args[1], TCG_REG_NONE, args[2]);
                   1958:         } else {
                   1959:             tcg_out_sh64(s, op, args[0], args[1], args[2], 0);
                   1960:         }
                   1961:         break;
                   1962:     case INDEX_op_shr_i64:
                   1963:         op = RSY_SRLG;
                   1964:         goto do_shift64;
                   1965:     case INDEX_op_sar_i64:
                   1966:         op = RSY_SRAG;
                   1967:         goto do_shift64;
                   1968: 
                   1969:     case INDEX_op_rotl_i64:
                   1970:         if (const_args[2]) {
                   1971:             tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
                   1972:                          TCG_REG_NONE, args[2]);
                   1973:         } else {
                   1974:             tcg_out_sh64(s, RSY_RLLG, args[0], args[1], args[2], 0);
                   1975:         }
                   1976:         break;
                   1977:     case INDEX_op_rotr_i64:
                   1978:         if (const_args[2]) {
                   1979:             tcg_out_sh64(s, RSY_RLLG, args[0], args[1],
                   1980:                          TCG_REG_NONE, (64 - args[2]) & 63);
                   1981:         } else {
                   1982:             /* We can use the smaller 32-bit negate because only the
                   1983:                low 6 bits are examined for the rotate.  */
                   1984:             tcg_out_insn(s, RR, LCR, TCG_TMP0, args[2]);
                   1985:             tcg_out_sh64(s, RSY_RLLG, args[0], args[1], TCG_TMP0, 0);
                   1986:         }
                   1987:         break;
                   1988: 
                   1989:     case INDEX_op_ext8s_i64:
                   1990:         tgen_ext8s(s, TCG_TYPE_I64, args[0], args[1]);
                   1991:         break;
                   1992:     case INDEX_op_ext16s_i64:
                   1993:         tgen_ext16s(s, TCG_TYPE_I64, args[0], args[1]);
                   1994:         break;
                   1995:     case INDEX_op_ext32s_i64:
                   1996:         tgen_ext32s(s, args[0], args[1]);
                   1997:         break;
                   1998:     case INDEX_op_ext8u_i64:
                   1999:         tgen_ext8u(s, TCG_TYPE_I64, args[0], args[1]);
                   2000:         break;
                   2001:     case INDEX_op_ext16u_i64:
                   2002:         tgen_ext16u(s, TCG_TYPE_I64, args[0], args[1]);
                   2003:         break;
                   2004:     case INDEX_op_ext32u_i64:
                   2005:         tgen_ext32u(s, args[0], args[1]);
                   2006:         break;
                   2007: 
                   2008:     case INDEX_op_brcond_i64:
                   2009:         tgen_brcond(s, TCG_TYPE_I64, args[2], args[0],
                   2010:                     args[1], const_args[1], args[3]);
                   2011:         break;
                   2012:     case INDEX_op_setcond_i64:
                   2013:         tgen_setcond(s, TCG_TYPE_I64, args[3], args[0], args[1],
                   2014:                      args[2], const_args[2]);
                   2015:         break;
                   2016: 
                   2017:     case INDEX_op_qemu_ld32u:
                   2018:         tcg_out_qemu_ld(s, args, LD_UINT32);
                   2019:         break;
                   2020:     case INDEX_op_qemu_ld32s:
                   2021:         tcg_out_qemu_ld(s, args, LD_INT32);
                   2022:         break;
                   2023: #endif /* TCG_TARGET_REG_BITS == 64 */
                   2024: 
                   2025:     case INDEX_op_jmp:
                   2026:         /* This one is obsolete and never emitted.  */
                   2027:         tcg_abort();
                   2028:         break;
                   2029: 
                   2030:     default:
                   2031:         fprintf(stderr,"unimplemented opc 0x%x\n",opc);
                   2032:         tcg_abort();
                   2033:     }
1.1       root     2034: }
                   2035: 
1.1.1.2   root     2036: static const TCGTargetOpDef s390_op_defs[] = {
                   2037:     { INDEX_op_exit_tb, { } },
                   2038:     { INDEX_op_goto_tb, { } },
                   2039:     { INDEX_op_call, { "ri" } },
                   2040:     { INDEX_op_jmp, { "ri" } },
                   2041:     { INDEX_op_br, { } },
                   2042: 
                   2043:     { INDEX_op_mov_i32, { "r", "r" } },
                   2044:     { INDEX_op_movi_i32, { "r" } },
                   2045: 
                   2046:     { INDEX_op_ld8u_i32, { "r", "r" } },
                   2047:     { INDEX_op_ld8s_i32, { "r", "r" } },
                   2048:     { INDEX_op_ld16u_i32, { "r", "r" } },
                   2049:     { INDEX_op_ld16s_i32, { "r", "r" } },
                   2050:     { INDEX_op_ld_i32, { "r", "r" } },
                   2051:     { INDEX_op_st8_i32, { "r", "r" } },
                   2052:     { INDEX_op_st16_i32, { "r", "r" } },
                   2053:     { INDEX_op_st_i32, { "r", "r" } },
                   2054: 
                   2055:     { INDEX_op_add_i32, { "r", "0", "rWI" } },
                   2056:     { INDEX_op_sub_i32, { "r", "0", "rWNI" } },
                   2057:     { INDEX_op_mul_i32, { "r", "0", "rK" } },
                   2058: 
                   2059:     { INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
                   2060:     { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
                   2061: 
                   2062:     { INDEX_op_and_i32, { "r", "0", "rWA" } },
                   2063:     { INDEX_op_or_i32, { "r", "0", "rWO" } },
                   2064:     { INDEX_op_xor_i32, { "r", "0", "rWX" } },
                   2065: 
                   2066:     { INDEX_op_neg_i32, { "r", "r" } },
                   2067: 
                   2068:     { INDEX_op_shl_i32, { "r", "0", "Ri" } },
                   2069:     { INDEX_op_shr_i32, { "r", "0", "Ri" } },
                   2070:     { INDEX_op_sar_i32, { "r", "0", "Ri" } },
                   2071: 
                   2072:     { INDEX_op_rotl_i32, { "r", "r", "Ri" } },
                   2073:     { INDEX_op_rotr_i32, { "r", "r", "Ri" } },
                   2074: 
                   2075:     { INDEX_op_ext8s_i32, { "r", "r" } },
                   2076:     { INDEX_op_ext8u_i32, { "r", "r" } },
                   2077:     { INDEX_op_ext16s_i32, { "r", "r" } },
                   2078:     { INDEX_op_ext16u_i32, { "r", "r" } },
                   2079: 
                   2080:     { INDEX_op_bswap16_i32, { "r", "r" } },
                   2081:     { INDEX_op_bswap32_i32, { "r", "r" } },
                   2082: 
                   2083:     { INDEX_op_brcond_i32, { "r", "rWC" } },
                   2084:     { INDEX_op_setcond_i32, { "r", "r", "rWC" } },
                   2085: 
                   2086:     { INDEX_op_qemu_ld8u, { "r", "L" } },
                   2087:     { INDEX_op_qemu_ld8s, { "r", "L" } },
                   2088:     { INDEX_op_qemu_ld16u, { "r", "L" } },
                   2089:     { INDEX_op_qemu_ld16s, { "r", "L" } },
                   2090:     { INDEX_op_qemu_ld32, { "r", "L" } },
                   2091:     { INDEX_op_qemu_ld64, { "r", "L" } },
                   2092: 
                   2093:     { INDEX_op_qemu_st8, { "L", "L" } },
                   2094:     { INDEX_op_qemu_st16, { "L", "L" } },
                   2095:     { INDEX_op_qemu_st32, { "L", "L" } },
                   2096:     { INDEX_op_qemu_st64, { "L", "L" } },
                   2097: 
                   2098: #if defined(__s390x__)
                   2099:     { INDEX_op_mov_i64, { "r", "r" } },
                   2100:     { INDEX_op_movi_i64, { "r" } },
                   2101: 
                   2102:     { INDEX_op_ld8u_i64, { "r", "r" } },
                   2103:     { INDEX_op_ld8s_i64, { "r", "r" } },
                   2104:     { INDEX_op_ld16u_i64, { "r", "r" } },
                   2105:     { INDEX_op_ld16s_i64, { "r", "r" } },
                   2106:     { INDEX_op_ld32u_i64, { "r", "r" } },
                   2107:     { INDEX_op_ld32s_i64, { "r", "r" } },
                   2108:     { INDEX_op_ld_i64, { "r", "r" } },
                   2109: 
                   2110:     { INDEX_op_st8_i64, { "r", "r" } },
                   2111:     { INDEX_op_st16_i64, { "r", "r" } },
                   2112:     { INDEX_op_st32_i64, { "r", "r" } },
                   2113:     { INDEX_op_st_i64, { "r", "r" } },
                   2114: 
                   2115:     { INDEX_op_add_i64, { "r", "0", "rI" } },
                   2116:     { INDEX_op_sub_i64, { "r", "0", "rNI" } },
                   2117:     { INDEX_op_mul_i64, { "r", "0", "rK" } },
                   2118: 
                   2119:     { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
                   2120:     { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
                   2121: 
                   2122:     { INDEX_op_and_i64, { "r", "0", "rA" } },
                   2123:     { INDEX_op_or_i64, { "r", "0", "rO" } },
                   2124:     { INDEX_op_xor_i64, { "r", "0", "rX" } },
                   2125: 
                   2126:     { INDEX_op_neg_i64, { "r", "r" } },
                   2127: 
                   2128:     { INDEX_op_shl_i64, { "r", "r", "Ri" } },
                   2129:     { INDEX_op_shr_i64, { "r", "r", "Ri" } },
                   2130:     { INDEX_op_sar_i64, { "r", "r", "Ri" } },
                   2131: 
                   2132:     { INDEX_op_rotl_i64, { "r", "r", "Ri" } },
                   2133:     { INDEX_op_rotr_i64, { "r", "r", "Ri" } },
                   2134: 
                   2135:     { INDEX_op_ext8s_i64, { "r", "r" } },
                   2136:     { INDEX_op_ext8u_i64, { "r", "r" } },
                   2137:     { INDEX_op_ext16s_i64, { "r", "r" } },
                   2138:     { INDEX_op_ext16u_i64, { "r", "r" } },
                   2139:     { INDEX_op_ext32s_i64, { "r", "r" } },
                   2140:     { INDEX_op_ext32u_i64, { "r", "r" } },
                   2141: 
                   2142:     { INDEX_op_bswap16_i64, { "r", "r" } },
                   2143:     { INDEX_op_bswap32_i64, { "r", "r" } },
                   2144:     { INDEX_op_bswap64_i64, { "r", "r" } },
                   2145: 
                   2146:     { INDEX_op_brcond_i64, { "r", "rC" } },
                   2147:     { INDEX_op_setcond_i64, { "r", "r", "rC" } },
                   2148: 
                   2149:     { INDEX_op_qemu_ld32u, { "r", "L" } },
                   2150:     { INDEX_op_qemu_ld32s, { "r", "L" } },
                   2151: #endif
                   2152: 
                   2153:     { -1 },
                   2154: };
                   2155: 
                   2156: /* ??? Linux kernels provide an AUXV entry AT_HWCAP that provides most of
                   2157:    this information.  However, getting at that entry is not easy this far
                   2158:    away from main.  Our options are: start searching from environ, but
                   2159:    that fails as soon as someone does a setenv in between.  Read the data
                   2160:    from /proc/self/auxv.  Or do the probing ourselves.  The only thing
                   2161:    extra that AT_HWCAP gives us is HWCAP_S390_HIGH_GPRS, which indicates
                   2162:    that the kernel saves all 64-bits of the registers around traps while
                   2163:    in 31-bit mode.  But this is true of all "recent" kernels (ought to dig
                   2164:    back and see from when this might not be true).  */
                   2165: 
                   2166: #include <signal.h>
                   2167: 
                   2168: static volatile sig_atomic_t got_sigill;
                   2169: 
                   2170: static void sigill_handler(int sig)
1.1       root     2171: {
1.1.1.2   root     2172:     got_sigill = 1;
1.1       root     2173: }
                   2174: 
1.1.1.2   root     2175: static void query_facilities(void)
1.1       root     2176: {
1.1.1.2   root     2177:     struct sigaction sa_old, sa_new;
                   2178:     register int r0 __asm__("0");
                   2179:     register void *r1 __asm__("1");
                   2180:     int fail;
                   2181: 
                   2182:     memset(&sa_new, 0, sizeof(sa_new));
                   2183:     sa_new.sa_handler = sigill_handler;
                   2184:     sigaction(SIGILL, &sa_new, &sa_old);
                   2185: 
                   2186:     /* First, try STORE FACILITY LIST EXTENDED.  If this is present, then
                   2187:        we need not do any more probing.  Unfortunately, this itself is an
                   2188:        extension and the original STORE FACILITY LIST instruction is
                   2189:        kernel-only, storing its results at absolute address 200.  */
                   2190:     /* stfle 0(%r1) */
                   2191:     r1 = &facilities;
                   2192:     asm volatile(".word 0xb2b0,0x1000"
                   2193:                  : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
                   2194: 
                   2195:     if (got_sigill) {
                   2196:         /* STORE FACILITY EXTENDED is not available.  Probe for one of each
                   2197:            kind of instruction that we're interested in.  */
                   2198:         /* ??? Possibly some of these are in practice never present unless
                   2199:            the store-facility-extended facility is also present.  But since
                   2200:            that isn't documented it's just better to probe for each.  */
                   2201: 
                   2202:         /* Test for z/Architecture.  Required even in 31-bit mode.  */
                   2203:         got_sigill = 0;
                   2204:         /* agr %r0,%r0 */
                   2205:         asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
                   2206:         if (!got_sigill) {
                   2207:             facilities |= FACILITY_ZARCH_ACTIVE;
                   2208:         }
                   2209: 
                   2210:         /* Test for long displacement.  */
                   2211:         got_sigill = 0;
                   2212:         /* ly %r0,0(%r1) */
                   2213:         r1 = &facilities;
                   2214:         asm volatile(".word 0xe300,0x1000,0x0058"
                   2215:                      : "=r"(r0) : "r"(r1) : "cc");
                   2216:         if (!got_sigill) {
                   2217:             facilities |= FACILITY_LONG_DISP;
                   2218:         }
                   2219: 
                   2220:         /* Test for extended immediates.  */
                   2221:         got_sigill = 0;
                   2222:         /* afi %r0,0 */
                   2223:         asm volatile(".word 0xc209,0x0000,0x0000" : : : "cc");
                   2224:         if (!got_sigill) {
                   2225:             facilities |= FACILITY_EXT_IMM;
                   2226:         }
                   2227: 
                   2228:         /* Test for general-instructions-extension.  */
                   2229:         got_sigill = 0;
                   2230:         /* msfi %r0,1 */
                   2231:         asm volatile(".word 0xc201,0x0000,0x0001");
                   2232:         if (!got_sigill) {
                   2233:             facilities |= FACILITY_GEN_INST_EXT;
                   2234:         }
                   2235:     }
                   2236: 
                   2237:     sigaction(SIGILL, &sa_old, NULL);
                   2238: 
                   2239:     /* The translator currently uses these extensions unconditionally.
                   2240:        Pruning this back to the base ESA/390 architecture doesn't seem
                   2241:        worthwhile, since even the KVM target requires z/Arch.  */
                   2242:     fail = 0;
                   2243:     if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
                   2244:         fprintf(stderr, "TCG: z/Arch facility is required.\n");
                   2245:         fprintf(stderr, "TCG: Boot with a 64-bit enabled kernel.\n");
                   2246:         fail = 1;
                   2247:     }
                   2248:     if ((facilities & FACILITY_LONG_DISP) == 0) {
                   2249:         fprintf(stderr, "TCG: long-displacement facility is required.\n");
                   2250:         fail = 1;
                   2251:     }
                   2252: 
                   2253:     /* So far there's just enough support for 31-bit mode to let the
                   2254:        compile succeed.  This is good enough to run QEMU with KVM.  */
                   2255:     if (sizeof(void *) != 8) {
                   2256:         fprintf(stderr, "TCG: 31-bit mode is not supported.\n");
                   2257:         fail = 1;
                   2258:     }
                   2259: 
                   2260:     if (fail) {
                   2261:         exit(-1);
                   2262:     }
1.1       root     2263: }
                   2264: 
1.1.1.2   root     2265: static void tcg_target_init(TCGContext *s)
1.1       root     2266: {
1.1.1.2   root     2267: #if !defined(CONFIG_USER_ONLY)
                   2268:     /* fail safe */
                   2269:     if ((1 << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) {
                   2270:         tcg_abort();
                   2271:     }
                   2272: #endif
                   2273: 
                   2274:     query_facilities();
                   2275: 
                   2276:     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
                   2277:     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffff);
                   2278: 
                   2279:     tcg_regset_clear(tcg_target_call_clobber_regs);
                   2280:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R0);
                   2281:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R1);
                   2282:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R2);
                   2283:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R3);
                   2284:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R4);
                   2285:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R5);
                   2286:     /* The return register can be considered call-clobbered.  */
                   2287:     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R14);
                   2288: 
                   2289:     tcg_regset_clear(s->reserved_regs);
                   2290:     tcg_regset_set_reg(s->reserved_regs, TCG_TMP0);
                   2291:     /* XXX many insns can't be used with R0, so we better avoid it for now */
                   2292:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R0);
                   2293:     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
                   2294: 
                   2295:     tcg_add_target_add_op_defs(s390_op_defs);
1.1.1.3   root     2296:     tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
                   2297:                   CPU_TEMP_BUF_NLONGS * sizeof(long));
1.1.1.2   root     2298: }
                   2299: 
                   2300: static void tcg_target_qemu_prologue(TCGContext *s)
                   2301: {
                   2302:     /* stmg %r6,%r15,48(%r15) (save registers) */
                   2303:     tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
                   2304: 
                   2305:     /* aghi %r15,-160 (stack frame) */
                   2306:     tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -160);
                   2307: 
                   2308:     if (GUEST_BASE >= 0x80000) {
                   2309:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
                   2310:         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
                   2311:     }
                   2312: 
1.1.1.3   root     2313:     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
                   2314:     /* br %r3 (go to TB) */
                   2315:     tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
1.1.1.2   root     2316: 
                   2317:     tb_ret_addr = s->code_ptr;
                   2318: 
                   2319:     /* lmg %r6,%r15,208(%r15) (restore registers) */
                   2320:     tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 208);
                   2321: 
                   2322:     /* br %r14 (return) */
                   2323:     tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
1.1       root     2324: }

unix.superglobalmegacorp.com

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