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

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

unix.superglobalmegacorp.com

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