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

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);
        !          2294: }
        !          2295: 
        !          2296: static void tcg_target_qemu_prologue(TCGContext *s)
        !          2297: {
        !          2298:     /* stmg %r6,%r15,48(%r15) (save registers) */
        !          2299:     tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48);
        !          2300: 
        !          2301:     /* aghi %r15,-160 (stack frame) */
        !          2302:     tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -160);
        !          2303: 
        !          2304:     if (GUEST_BASE >= 0x80000) {
        !          2305:         tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
        !          2306:         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
        !          2307:     }
        !          2308: 
        !          2309:     /* br %r2 (go to TB) */
        !          2310:     tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R2);
        !          2311: 
        !          2312:     tb_ret_addr = s->code_ptr;
        !          2313: 
        !          2314:     /* lmg %r6,%r15,208(%r15) (restore registers) */
        !          2315:     tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 208);
        !          2316: 
        !          2317:     /* br %r14 (return) */
        !          2318:     tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14);
1.1       root     2319: }
                   2320: 
                   2321: static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
                   2322: {
                   2323:     tcg_abort();
                   2324: }

unix.superglobalmegacorp.com

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